home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / comm / vt100r29.3 < prev    next >
Internet Message Format  |  1989-10-20  |  77KB

  1. Path: xanth!mcnc!rutgers!ucsd!tut.cis.ohio-state.edu!mailrus!ames!sun-barr!newstop!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i180:  vt100 - terminal emulator v2.9, Part03/09
  5. Message-ID: <126577@sun.Eng.Sun.COM>
  6. Date: 20 Oct 89 06:09:34 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 3266
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: acs@pccuts.pcc.amdahl.com (Tony Sumrall)
  12. Posting-number: Volume 89, Issue 180
  13. Archive-name: comm/vt100r29.3
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    Zmodem/rbsb.c
  24. #    Zmodem/zm.c
  25. #    Zmodem/sz.c
  26. # This is archive 3 of a 9-part kit.
  27. # This archive created: Thu Oct 19 22:30:29 1989
  28. if `test ! -d Zmodem`
  29. then
  30.   mkdir Zmodem
  31.   echo "mkdir Zmodem"
  32. fi
  33. echo "extracting Zmodem/rbsb.c"
  34. sed 's/^X//' << \SHAR_EOF > Zmodem/rbsb.c
  35. X/*
  36. X *
  37. X * -rev 04-16-87
  38. X *  This file contains Unix specific code for setting terminal modes,
  39. X *  very little is specific to ZMODEM or YMODEM per se (that code is in
  40. X *  sz.c and rz.c).  The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM
  41. X *  are also in this file, a fast table driven macro version
  42. X *
  43. X *   This file is #included so the main file can set parameters such as HOWMANY.
  44. X *   See the main files (rz.c/sz.c) for compile instructions.
  45. X */
  46. X#ifdef AMIGA
  47. X#define OS "the Amiga"
  48. Xstruct IOExtSer *SetSer();
  49. XULONG Len,Stop,ParFlags;
  50. Xchar ParityCH; /* parity character N=none,E=even,O=odd */
  51. X
  52. X/*
  53. X * if op is 0 then clean up and prepare for exit
  54. X * if op is 1 then init serial port, timers etc.
  55. X * bomb for the other modes
  56. X */
  57. Xmode(op)
  58. Xint op;
  59. X{
  60. X  struct IOExtSer *Ser;
  61. X
  62. X  switch(op)
  63. X   {
  64. X    case 1:if( SetTimer()!=0 ) return ERROR;
  65. X           else {
  66. X            InitParams();
  67. X            if( (Ser=SetSer(InitSer?Baudrate:-1,Len,Stop,SERF_SHARED|SERF_XDISABLED|ParFlags))==NULL )
  68. X               return ERROR;
  69. X           }
  70. X           UpDateParms(Ser);
  71. X           fprintf(stderr,"Transferring at %d baud, %d%c%d\n",Baudrate,Len,ParityCH,Stop);
  72. X#ifndef RZ     /* sz needs bigger buffer for higher speeds */
  73. X           if (Baudrate > 300)
  74. X            BufferSize = 256;
  75. X           if (Baudrate > 1200)
  76. X            BufferSize = 512;
  77. X           if (Baudrate > 2400)
  78. X            BufferSize = KSIZE;
  79. X           if (Rxbuflen && BufferSize>Rxbuflen)
  80. X            BufferSize = Rxbuflen;
  81. X           if (blkopt && BufferSize > blkopt)
  82. X            BufferSize = blkopt;
  83. X           Next=OutBuf=(UBYTE *)malloc(BufferSize);
  84. X#endif
  85. X        return OK;
  86. X
  87. X    case 0:
  88. X           CloseSer();
  89. X           CloseTimer();
  90. X#ifndef RZ
  91. X           if(OutBuf) free(OutBuf);
  92. X#endif
  93. X           return OK;
  94. X
  95. X    default: /* bomb for other modes */
  96. X         return ERROR;
  97. X    }
  98. X
  99. X}
  100. X
  101. XInitParams()
  102. X{
  103. X FILE *fparm;
  104. X
  105. X  if( (fparm=fopen("zmodem.init","r"))==NULL &&
  106. X      (fparm=fopen("S:zmodem.init","r"))==NULL)
  107. X  {
  108. X    /* default to preferences */
  109. X    InitSer = FALSE;
  110. X   }
  111. X  else
  112. X      {
  113. X       gmt_diff=100;
  114. X       fscanf(fparm,"%d %d%c%d %d",&Baudrate,&Len,&ParityCH,&Stop,&gmt_diff);
  115. X       if(gmt_diff!=100) gmt_diff_set=TRUE;
  116. X       fclose(fparm);
  117. X       switch(ParityCH)
  118. X       {
  119. X    case 'E':
  120. X    case 'e': ParFlags = SERF_PARTY_ON;break;
  121. X
  122. X    case 'o':
  123. X    case 'O': ParFlags = SERF_PARTY_ON|SERF_PARTY_ODD;break;
  124. X
  125. X    default : ParFlags = NULL;
  126. X       }
  127. X }
  128. X}
  129. X
  130. XUpDateParms(SS)
  131. Xstruct IOExtSer *SS;
  132. X{
  133. X  if( !InitSer)
  134. X  {
  135. X    Baudrate = SS->io_Baud;
  136. X    Len      = SS->io_ReadLen;
  137. X    Stop     = SS->io_StopBits;
  138. X    if( SS->io_SerFlags & SERF_PARTY_ON)
  139. X    {
  140. X    if( SS->io_SerFlags & SERF_PARTY_ODD)
  141. X        ParityCH = 'O';
  142. X    else
  143. X        ParityCH= 'E';
  144. X     }
  145. X    else
  146. X    ParityCH = 'N';
  147. X   }
  148. X  if( Len<8 || ParityCH!='N')
  149. X   {
  150. X     /* set 7 bit text mode */
  151. X     Wcsmask = 0177;
  152. X#ifdef RZ
  153. X     Rxascii=TRUE;
  154. X#else
  155. X     Lzconv = 2;   /* This 2 is really ZCNL, but the way the includes are */
  156. X     Ascii = TRUE; /* set up I had to hack it this way */
  157. X#endif
  158. X    }
  159. X}
  160. X
  161. Xsleep(n)
  162. Xint n;
  163. X{
  164. X
  165. X
  166. X   if(n>0) Delay (50*n);
  167. X   return (0);
  168. X}
  169. X#else /* UNIX versions */
  170. X#ifdef V7
  171. X#include <sys/types.h>
  172. X#include <sys/stat.h>
  173. X#include <sgtty.h>
  174. X#define OS "V7/BSD"
  175. X#endif
  176. X
  177. X#ifndef OS
  178. X#ifndef USG
  179. X#define USG
  180. X#endif
  181. X#endif
  182. X
  183. X#ifdef USG
  184. X#include <sys/types.h>
  185. X#include <sys/stat.h>
  186. X#include <termio.h>
  187. X#include <sys/ioctl.h>
  188. X#define OS "SYS III/V"
  189. X#endif
  190. X
  191. X#if HOWMANY  > 255
  192. XHowmany must be 255 or less
  193. X#endif
  194. X
  195. Xstruct {
  196. X    unsigned baudr;
  197. X    int speedcode;
  198. X} speeds[] = {
  199. X    110,    B110,
  200. X    300,    B300,
  201. X    600,    B600,
  202. X    1200,    B1200,
  203. X    2400,    B2400,
  204. X    4800,    B4800,
  205. X    9600,    B9600,
  206. X    19200,    EXTA,
  207. X    9600,    EXTB,
  208. X    0,
  209. X};
  210. X
  211. Xint Twostop;        /* Use two stop bits */
  212. X
  213. Xstatic unsigned
  214. Xgetspeed(code)
  215. X{
  216. X    register n;
  217. X
  218. X    for (n=0; speeds[n].baudr; ++n)
  219. X        if (speeds[n].speedcode == code)
  220. X            return speeds[n].baudr;
  221. X    return 0;
  222. X}
  223. X
  224. X
  225. X
  226. X#ifdef ICANON
  227. Xstruct termio oldtty, tty;
  228. X#else
  229. Xstruct sgttyb oldtty, tty;
  230. Xstruct tchars oldtch, tch;
  231. X#endif
  232. X
  233. Xint iofd = 0;        /* File descriptor for ioctls & reads */
  234. X
  235. X/*
  236. X * mode(n)
  237. X *  3: save old tty stat, set raw mode with flow control
  238. X *  2: set a cbreak, XON/XOFF control mode if using Pro-YAM's -g option
  239. X *  1: save old tty stat, set raw mode
  240. X *  0: restore original tty mode
  241. X */
  242. Xmode(n)
  243. X{
  244. X    static did0 = FALSE;
  245. X
  246. X    vfile("mode:%d", n);
  247. X    switch(n) {
  248. X#ifdef USG
  249. X    case 2: /* Cbreak mode used by sb when -g detected */
  250. X        if(!did0)
  251. X            (void) ioctl(iofd, TCGETA, &oldtty);
  252. X        tty = oldtty;
  253. X
  254. X        tty.c_iflag = BRKINT|IXON;
  255. X
  256. X        tty.c_oflag = 0;    /* Transparent output */
  257. X
  258. X        tty.c_cflag &= ~PARENB; /* Disable parity */
  259. X        tty.c_cflag |= CS8;    /* Set character size = 8 */
  260. X        if (Twostop)
  261. X            tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  262. X
  263. X        tty.c_lflag =
  264. X#ifdef XCLUDE
  265. X          XCLUDE |
  266. X#endif
  267. X          Zmodem ? 0 : ISIG;
  268. X
  269. X        tty.c_cc[VINTR] = 030;        /* Interrupt char */
  270. X        tty.c_cc[VMIN] = 1;
  271. X
  272. X        (void) ioctl(iofd, TCSETAW, &tty);
  273. X        did0 = TRUE;
  274. X        return OK;
  275. X    case 1:
  276. X    case 3:
  277. X        if(!did0)
  278. X            (void) ioctl(iofd, TCGETA, &oldtty);
  279. X        tty = oldtty;
  280. X
  281. X        tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK;
  282. X
  283. X         /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
  284. X        tty.c_lflag &= ~(ECHO | ICANON | ISIG);
  285. X#ifdef XCLUDE
  286. X        tty.c_lflag |= XCLUDE;
  287. X#endif
  288. X
  289. X        tty.c_oflag = 0;    /* Transparent output */
  290. X
  291. X        tty.c_cflag &= ~PARENB; /* Same baud rate, disable parity */
  292. X        tty.c_cflag |= CS8;    /* Set character size = 8 */
  293. X        if (Twostop)
  294. X            tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  295. X#ifdef NFGVMIN
  296. X        tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
  297. X#else
  298. X        tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
  299. X#endif
  300. X        tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  301. X        (void) ioctl(iofd, TCSETAW, &tty);
  302. X        did0 = TRUE;
  303. X        Baudrate = getspeed(tty.c_cflag & CBAUD);
  304. X        return OK;
  305. X#endif
  306. X#ifdef V7
  307. X    case 2: /*  This doesn't work ... */
  308. X        printf("No mode(2) in V7/BSD!"); bibi(99);
  309. X        if(!did0) {
  310. X            ioctl(iofd, TIOCEXCL, 0);
  311. X            ioctl(iofd, TIOCGETP, &oldtty);
  312. X            ioctl(iofd, TIOCGETC, &oldtch);
  313. X        }
  314. X        tty = oldtty;
  315. X        tch = oldtch;
  316. X        tch.t_intrc = Zmodem ? 03:030;    /* Interrupt char */
  317. X        tty.sg_flags |= (ODDP|EVENP|CBREAK);
  318. X        tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
  319. X        ioctl(iofd, TIOCSETP, &tty);
  320. X        ioctl(iofd, TIOCSETC, &tch);
  321. X        did0 = TRUE;
  322. X        return OK;
  323. X    case 1:
  324. X    case 3:
  325. X        if(!did0) {
  326. X            ioctl(iofd, TIOCEXCL, 0);
  327. X            ioctl(iofd, TIOCGETP, &oldtty);
  328. X            ioctl(iofd, TIOCGETC, &oldtch);
  329. X        }
  330. X        tty = oldtty;
  331. X        tty.sg_flags |= RAW;
  332. X        tty.sg_flags &= ~ECHO;
  333. X        ioctl(iofd, TIOCSETP, &tty);
  334. X        did0 = TRUE;
  335. X        Baudrate = getspeed(tty.sg_ospeed);
  336. X        return OK;
  337. X#endif
  338. X    case 0:
  339. X        if(!did0)
  340. X            return ERROR;
  341. X#ifdef USG
  342. X        (void) ioctl(iofd, TCSBRK, 1);  /* Wait for output to drain */
  343. X        (void) ioctl(iofd, TCFLSH, 1);  /* Flush input queue */
  344. X        (void) ioctl(iofd, TCSETAW, &oldtty);   /* Restore original modes */
  345. X        (void) ioctl(iofd, TCXONC,1);   /* Restart output */
  346. X#endif
  347. X#ifdef V7
  348. X        ioctl(iofd, TIOCSETP, &oldtty);
  349. X        ioctl(iofd, TIOCSETC, &oldtch);
  350. X        ioctl(iofd, TIOCNXCL, 0);
  351. X#endif
  352. X        return OK;
  353. X    default:
  354. X        return ERROR;
  355. X    }
  356. X}
  357. X#endif
  358. X
  359. Xsendbrk()
  360. X{
  361. X#ifdef AMIGA
  362. X    SendBreak();
  363. X#else
  364. X#ifdef V7
  365. X#ifdef TIOCSBRK
  366. X#define CANBREAK
  367. X    sleep(1);
  368. X    ioctl(iofd, TIOCSBRK, 0);
  369. X    sleep(1);
  370. X    ioctl(iofd, TIOCCBRK, 0);
  371. X#endif
  372. X#endif
  373. X#ifdef USG
  374. X#define CANBREAK
  375. X    ioctl(iofd, TCSBRK, 0);
  376. X#endif
  377. X#endif /* AMIGA */
  378. X}
  379. X
  380. X#ifdef AMIGA
  381. Xrdchk()
  382. X{
  383. X    if (SerOpen) {
  384. X    if (Lleft>0) return Lleft;
  385. X    else return CharsWaiting();
  386. X    }
  387. X}
  388. X#else
  389. X#ifdef FIONREAD
  390. X#define READCHECK
  391. X/*
  392. X *  Return non 0 iff something to read from io descriptor f
  393. X */
  394. Xrdchk(f)
  395. X{
  396. X    static long lf;
  397. X
  398. X    ioctl(f, FIONREAD, &lf);
  399. X    return ((int) lf);
  400. X}
  401. X#endif
  402. X#ifdef SVR2
  403. X#define READCHECK
  404. X#include <fcntl.h>
  405. X
  406. Xchar checked = '\0' ;
  407. X/*
  408. X * Nonblocking I/O is a bit different in System V, Release 2
  409. X */
  410. Xrdchk(f)
  411. X{
  412. X    int lf, savestat = fcntl(f, F_GETFL) ;
  413. X
  414. X    fcntl(f, F_SETFL, savestat | O_NDELAY) ;
  415. X    lf = read(f, &checked, 1) ;
  416. X    fcntl(f, F_SETFL, savestat) ;
  417. X    return(lf) ;
  418. X}
  419. X#endif
  420. X#endif
  421. X
  422. X/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
  423. Xstatic unsigned short crctab[256] = {
  424. X    0x0000,  0x1021,  0x2042,  0x3063,    0x4084,  0x50a5,  0x60c6,  0x70e7,
  425. X    0x8108,  0x9129,  0xa14a,  0xb16b,    0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
  426. X    0x1231,  0x0210,  0x3273,  0x2252,    0x52b5,  0x4294,  0x72f7,  0x62d6,
  427. X    0x9339,  0x8318,  0xb37b,  0xa35a,    0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
  428. X    0x2462,  0x3443,  0x0420,  0x1401,    0x64e6,  0x74c7,  0x44a4,  0x5485,
  429. X    0xa56a,  0xb54b,  0x8528,  0x9509,    0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
  430. X    0x3653,  0x2672,  0x1611,  0x0630,    0x76d7,  0x66f6,  0x5695,  0x46b4,
  431. X    0xb75b,  0xa77a,  0x9719,  0x8738,    0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
  432. X    0x48c4,  0x58e5,  0x6886,  0x78a7,    0x0840,  0x1861,  0x2802,  0x3823,
  433. X    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,    0x8948,  0x9969,  0xa90a,  0xb92b,
  434. X    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,    0x1a71,  0x0a50,  0x3a33,  0x2a12,
  435. X    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,    0x9b79,  0x8b58,  0xbb3b,  0xab1a,
  436. X    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,    0x2c22,  0x3c03,  0x0c60,  0x1c41,
  437. X    0xedae,  0xfd8f,  0xcdec,  0xddcd,    0xad2a,  0xbd0b,  0x8d68,  0x9d49,
  438. X    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,    0x3e13,  0x2e32,  0x1e51,  0x0e70,
  439. X    0xff9f,  0xefbe,  0xdfdd,  0xcffc,    0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
  440. X    0x9188,  0x81a9,  0xb1ca,  0xa1eb,    0xd10c,  0xc12d,  0xf14e,  0xe16f,
  441. X    0x1080,  0x00a1,  0x30c2,  0x20e3,    0x5004,  0x4025,  0x7046,  0x6067,
  442. X    0x83b9,  0x9398,  0xa3fb,  0xb3da,    0xc33d,  0xd31c,  0xe37f,  0xf35e,
  443. X    0x02b1,  0x1290,  0x22f3,  0x32d2,    0x4235,  0x5214,  0x6277,  0x7256,
  444. X    0xb5ea,  0xa5cb,  0x95a8,  0x8589,    0xf56e,  0xe54f,  0xd52c,  0xc50d,
  445. X    0x34e2,  0x24c3,  0x14a0,  0x0481,    0x7466,  0x6447,  0x5424,  0x4405,
  446. X    0xa7db,  0xb7fa,  0x8799,  0x97b8,    0xe75f,  0xf77e,  0xc71d,  0xd73c,
  447. X    0x26d3,  0x36f2,  0x0691,  0x16b0,    0x6657,  0x7676,  0x4615,  0x5634,
  448. X    0xd94c,  0xc96d,  0xf90e,  0xe92f,    0x99c8,  0x89e9,  0xb98a,  0xa9ab,
  449. X    0x5844,  0x4865,  0x7806,  0x6827,    0x18c0,  0x08e1,  0x3882,  0x28a3,
  450. X    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,    0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
  451. X    0x4a75,  0x5a54,  0x6a37,  0x7a16,    0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
  452. X    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,    0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
  453. X    0x7c26,  0x6c07,  0x5c64,  0x4c45,    0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
  454. X    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,    0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
  455. X    0x6e17,  0x7e36,  0x4e55,  0x5e74,    0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
  456. X};
  457. X
  458. X/*
  459. X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
  460. X *  NOTE: First srgument must be in range 0 to 255.
  461. X *      Second argument is referenced twice.
  462. X *
  463. X * Programmers may incorporate any or all code into their programs,
  464. X * giving proper credit within the source. Publication of the
  465. X * source routines is permitted so long as proper credit is given
  466. X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
  467. X * Omen Technology.
  468. X */
  469. X
  470. X#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
  471. X
  472. X/*
  473. X * Copyright (C) 1986 Gary S. Brown.  You may use this program, or
  474. X * code or tables extracted from it, as desired without restriction.
  475. X */
  476. X
  477. X/* First, the polynomial itself and its table of feedback terms.  The  */
  478. X/* polynomial is                               */
  479. X/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
  480. X/* Note that we take it "backwards" and put the highest-order term in  */
  481. X/* the lowest-order bit.  The X^32 term is "implied"; the LSB is the   */
  482. X/* X^31 term, etc.  The X^0 term (usually shown as "+1") results in    */
  483. X/* the MSB being 1.                               */
  484. X
  485. X/* Note that the usual hardware shift register implementation, which   */
  486. X/* is what we're using (we're merely optimizing it by doing eight-bit  */
  487. X/* chunks at a time) shifts bits into the lowest-order term.  In our   */
  488. X/* implementation, that means shifting towards the right.  Why do we   */
  489. X/* do it this way?  Because the calculated CRC must be transmitted in  */
  490. X/* order from highest-order term to lowest-order term.    UARTs transmit */
  491. X/* characters in order from LSB to MSB.  By storing the CRC this way,  */
  492. X/* we hand it to the UART in the order low-byte to high-byte; the UART */
  493. X/* sends each low-bit to hight-bit; and the result is transmission bit */
  494. X/* by bit from highest- to lowest-order term without requiring any bit */
  495. X/* shuffling on our part.  Reception works similarly.               */
  496. X
  497. X/* The feedback terms table consists of 256, 32-bit entries.  Notes:   */
  498. X/*                                       */
  499. X/*     The table can be generated at runtime if desired; code to do so */
  500. X/*     is shown later.    It might not be obvious, but the feedback      */
  501. X/*     terms simply represent the results of eight shift/xor opera-    */
  502. X/*     tions for all combinations of data and CRC register values.     */
  503. X/*                                       */
  504. X/*     The values must be right-shifted by eight bits by the "updcrc"  */
  505. X/*     logic; the shift must be unsigned (bring in zeroes).  On some   */
  506. X/*     hardware you could probably optimize the shift in assembler by  */
  507. X/*     using byte-swap instructions.                       */
  508. X
  509. Xstatic long cr3tab[] = { /* CRC polynomial 0xedb88320 */
  510. X0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
  511. X0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
  512. X0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
  513. X0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
  514. X0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
  515. X0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
  516. X0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
  517. X0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
  518. X0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
  519. X0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
  520. X0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
  521. X0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
  522. X0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
  523. X0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
  524. X0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
  525. X0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
  526. X0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
  527. X0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
  528. X0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
  529. X0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
  530. X0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
  531. X0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
  532. X0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
  533. X0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
  534. X0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
  535. X0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
  536. X0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
  537. X0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
  538. X0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
  539. X0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
  540. X0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
  541. X0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
  542. X};
  543. X
  544. X#ifdef NFGM
  545. Xlong
  546. XUPDC32(b, c)
  547. Xlong c;
  548. X{
  549. X    return (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF));
  550. X}
  551. X
  552. X#else
  553. X
  554. X#define UPDC32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
  555. X#endif
  556. X
  557. X/* End of rbsb.c */
  558. SHAR_EOF
  559. echo "extracting Zmodem/zm.c"
  560. sed 's/^X//' << \SHAR_EOF > Zmodem/zm.c
  561. X/*
  562. X *   Z M . C
  563. X *    ZMODEM protocol primitives
  564. X *    07-28-87    Chuck Forsberg Omen Technology Inc
  565. X *
  566. X * Entry point Functions:
  567. X *    zsbhdr(type, hdr) send binary header
  568. X *    zshhdr(type, hdr) send hex header
  569. X *    zgethdr(hdr, eflag) receive header - binary or hex
  570. X *    zsdata(buf, len, frameend) send data
  571. X *    zrdata(buf, len) receive data
  572. X *    stohdr(pos) store position data in Txhdr
  573. X *    long rclhdr(hdr) recover position offset from header
  574. X */
  575. X
  576. X#ifndef CANFDX
  577. X#include "zmodem.h"
  578. Xint Rxtimeout = 100;        /* Tenths of seconds to wait for something */
  579. X#endif
  580. X
  581. X
  582. X#ifndef UNSL
  583. X#define UNSL
  584. X#endif
  585. X
  586. X
  587. X/* Globals used by ZMODEM functions */
  588. Xint Rxframeind;     /* ZBIN ZBIN32, or ZHEX type of frame received */
  589. Xint Rxtype;        /* Type of header received */
  590. Xint Rxcount;        /* Count of data bytes received */
  591. Xchar Rxhdr[4];        /* Received header */
  592. Xchar Txhdr[4];        /* Transmitted header */
  593. Xlong Rxpos;        /* Received file position */
  594. Xlong Txpos;        /* Transmitted file position */
  595. Xint Txfcs32;        /* TURE means send binary frames with 32 bit FCS */
  596. Xint Crc32t;        /* Display flag indicating 32 bit CRC being sent */
  597. Xint Crc32;        /* Display flag indicating 32 bit CRC being received */
  598. Xint Znulls;        /* Number of nulls to send at beginning of ZDATA hdr */
  599. Xchar Attn[ZATTNLEN+1];    /* Attention string rx sends to tx on err */
  600. X
  601. X
  602. Xstatic char *frametypes[] = {
  603. X    "Carrier Lost",         /* -3 */
  604. X    "TIMEOUT",              /* -2 */
  605. X    "ERROR",                /* -1 */
  606. X#define FTOFFSET 3
  607. X    "ZRQINIT",
  608. X    "ZRINIT",
  609. X    "ZSINIT",
  610. X    "ZACK",
  611. X    "ZFILE",
  612. X    "ZSKIP",
  613. X    "ZNAK",
  614. X    "ZABORT",
  615. X    "ZFIN",
  616. X    "ZRPOS",
  617. X    "ZDATA",
  618. X    "ZEOF",
  619. X    "ZFERR",
  620. X    "ZCRC",
  621. X    "ZCHALLENGE",
  622. X    "ZCOMPL",
  623. X    "ZCAN",
  624. X    "ZFREECNT",
  625. X    "ZCOMMAND",
  626. X    "ZSTDERR",
  627. X    "xxxxx"
  628. X#define FRTYPES 22    /* Total number of frame types in this array */
  629. X            /*  not including psuedo negative entries */
  630. X};
  631. X
  632. X/* Send ZMODEM binary header hdr of type type */
  633. Xzsbhdr(type, hdr)
  634. Xregister char *hdr;
  635. X{
  636. X    register n;
  637. X    register unsigned short crc;
  638. X
  639. X    vfile("zsbhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
  640. X    if (type == ZDATA)
  641. X        for (n = Znulls; --n >=0; )
  642. X            zsendline(0);
  643. X
  644. X    xsendline(ZPAD); xsendline(ZDLE);
  645. X
  646. X    if (Crc32t=Txfcs32)
  647. X        zsbh32(hdr, type);
  648. X    else {
  649. X        xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0);
  650. X
  651. X        for (n=4; --n >= 0; ++hdr) {
  652. X            zsendline(*hdr);
  653. X            crc = updcrc((0377& *hdr), crc);
  654. X        }
  655. X        crc = updcrc(0,updcrc(0,crc));
  656. X        zsendline(crc>>8);
  657. X        zsendline(crc);
  658. X    }
  659. X#ifndef AMIGA
  660. X    if (type != ZDATA)
  661. X        flushmo();
  662. X#else
  663. X    flushmo();
  664. X#endif
  665. X}
  666. X
  667. X
  668. X/* Send ZMODEM binary header hdr of type type */
  669. Xzsbh32(hdr, type)
  670. Xregister char *hdr;
  671. X{
  672. X    register n;
  673. X    register UNSL long crc;
  674. X
  675. X    xsendline(ZBIN32);  zsendline(type);
  676. X    crc = 0xFFFFFFFFL; crc = UPDC32(type, crc);
  677. X
  678. X    for (n=4; --n >= 0; ++hdr) {
  679. X        crc = UPDC32((0377 & *hdr), crc);
  680. X        zsendline(*hdr);
  681. X    }
  682. X    crc = ~crc;
  683. X    for (n=4; --n >= 0;) {
  684. X        zsendline((int)crc);
  685. X        crc >>= 8;
  686. X    }
  687. X#ifdef AMIGA
  688. X    flushmo();
  689. X#endif
  690. X}
  691. X
  692. X/* Send ZMODEM HEX header hdr of type type */
  693. Xzshhdr(type, hdr)
  694. Xregister char *hdr;
  695. X{
  696. X    register n;
  697. X    register unsigned short crc;
  698. X
  699. X    vfile("zshhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
  700. X    sendline(ZPAD); sendline(ZPAD); sendline(ZDLE); sendline(ZHEX);
  701. X    zputhex(type);
  702. X    Crc32t = 0;
  703. X
  704. X    crc = updcrc(type, 0);
  705. X    for (n=4; --n >= 0; ++hdr) {
  706. X        zputhex(*hdr); crc = updcrc((0377 & *hdr), crc);
  707. X    }
  708. X    crc = updcrc(0,updcrc(0,crc));
  709. X    zputhex(crc>>8); zputhex(crc);
  710. X
  711. X    /* Make it printable on remote machine */
  712. X    sendline(015); sendline(012);
  713. X    /*
  714. X     * Uncork the remote in case a fake XOFF has stopped data flow
  715. X     */
  716. X    if (type != ZFIN && type != ZACK)
  717. X        sendline(021);
  718. X    flushmo();
  719. X}
  720. X
  721. X/*
  722. X * Send binary array buf of length length, with ending ZDLE sequence frameend
  723. X */
  724. Xzsdata(buf, length, frameend)
  725. Xregister char *buf;
  726. X{
  727. X    register unsigned short crc;
  728. X
  729. X    vfile("zsdata: length=%d end=%x", length, frameend);
  730. X    if (Crc32t)
  731. X        zsda32(buf, length, frameend);
  732. X    else {
  733. X        crc = 0;
  734. X        for (;--length >= 0; ++buf) {
  735. X            zsendline(*buf); crc = updcrc((0377 & *buf), crc);
  736. X        }
  737. X        xsendline(ZDLE); xsendline(frameend);
  738. X        crc = updcrc(frameend, crc);
  739. X
  740. X        crc = updcrc(0,updcrc(0,crc));
  741. X        zsendline(crc>>8); zsendline(crc);
  742. X    }
  743. X    if (frameend == ZCRCW) {
  744. X        xsendline(XON);  flushmo();
  745. X    }
  746. X#ifdef AMIGA
  747. X    else flushmo();
  748. X#endif
  749. X}
  750. X
  751. Xzsda32(buf, length, frameend)
  752. Xregister char *buf;
  753. X{
  754. X    register UNSL long crc;
  755. X
  756. X    crc = 0xFFFFFFFFL;
  757. X    for (;--length >= 0;++buf) {
  758. X        crc = UPDC32((0377 & *buf), crc);
  759. X        zsendline(*buf);
  760. X    }
  761. X    xsendline(ZDLE); xsendline(frameend);
  762. X    crc = UPDC32(frameend, crc);
  763. X
  764. X    crc = ~crc;
  765. X    for (length=4; --length >= 0;) {
  766. X        zsendline((int)crc);  crc >>= 8;
  767. X    }
  768. X}
  769. X
  770. X/*
  771. X * Receive array buf of max length with ending ZDLE sequence
  772. X *  and CRC.  Returns the ending character or error code.
  773. X *  NB: On errors may store length+1 bytes!
  774. X */
  775. Xzrdata(buf, length)
  776. Xregister char *buf;
  777. X{
  778. X    register c;
  779. X    register unsigned short crc;
  780. X    register char *end;
  781. X    register d;
  782. X
  783. X    if (Rxframeind == ZBIN32)
  784. X        return zrdat32(buf, length);
  785. X
  786. X    crc = Rxcount = 0;  end = buf + length;
  787. X    while (buf <= end) {
  788. X        if ((c = zdlread()) & ~0377) {
  789. Xcrcfoo:
  790. X            switch (c) {
  791. X            case GOTCRCE:
  792. X            case GOTCRCG:
  793. X            case GOTCRCQ:
  794. X            case GOTCRCW:
  795. X                crc = updcrc((d=c)&0377, crc);
  796. X                if ((c = zdlread()) & ~0377)
  797. X                    goto crcfoo;
  798. X                crc = updcrc(c, crc);
  799. X                if ((c = zdlread()) & ~0377)
  800. X                    goto crcfoo;
  801. X                crc = updcrc(c, crc);
  802. X                if (crc & 0xFFFF) {
  803. X                    zperr("Bad data CRC");
  804. X                    return ERROR;
  805. X                }
  806. X                Rxcount = length - (end - buf);
  807. X                vfile("zrdata: cnt = %d ret = %x", Rxcount, d);
  808. X                return d;
  809. X            case GOTCAN:
  810. X                zperr("Sender Canceled");
  811. X                return ZCAN;
  812. X            case TIMEOUT:
  813. X                zperr("TIMEOUT");
  814. X                return c;
  815. X            default:
  816. X                zperr("Bad data subpacket");
  817. X                return c;
  818. X            }
  819. X        }
  820. X        *buf++ = c;
  821. X        crc = updcrc(c, crc);
  822. X    }
  823. X    zperr("Data subpacket too long");
  824. X    return ERROR;
  825. X}
  826. X
  827. Xzrdat32(buf, length)
  828. Xregister char *buf;
  829. X{
  830. X    register c;
  831. X    register UNSL long crc;
  832. X    register char *end;
  833. X    register d;
  834. X
  835. X    crc = 0xFFFFFFFFL;  Rxcount = 0;  end = buf + length;
  836. X    while (buf <= end) {
  837. X        if ((c = zdlread()) & ~0377) {
  838. Xcrcfoo:
  839. X            switch (c) {
  840. X            case GOTCRCE:
  841. X            case GOTCRCG:
  842. X            case GOTCRCQ:
  843. X            case GOTCRCW:
  844. X                d = c;    c &= 0377;
  845. X                crc = UPDC32(c, crc);
  846. X                if ((c = zdlread()) & ~0377)
  847. X                    goto crcfoo;
  848. X                crc = UPDC32(c, crc);
  849. X                if ((c = zdlread()) & ~0377)
  850. X                    goto crcfoo;
  851. X                crc = UPDC32(c, crc);
  852. X                if ((c = zdlread()) & ~0377)
  853. X                    goto crcfoo;
  854. X                crc = UPDC32(c, crc);
  855. X                if ((c = zdlread()) & ~0377)
  856. X                    goto crcfoo;
  857. X                crc = UPDC32(c, crc);
  858. X                if (crc != 0xDEBB20E3) {
  859. X                    zperr("Bad data CRC");
  860. X                    return ERROR;
  861. X                }
  862. X                Rxcount = length - (end - buf);
  863. X                vfile("zrdat32: cnt = %d ret = %x", Rxcount, d);
  864. X                return d;
  865. X            case GOTCAN:
  866. X                zperr("Sender Canceled");
  867. X                return ZCAN;
  868. X            case TIMEOUT:
  869. X                zperr("TIMEOUT");
  870. X                return c;
  871. X            default:
  872. X                zperr("Bad data subpacket");
  873. X                return c;
  874. X            }
  875. X        }
  876. X        *buf++ = c;
  877. X        crc = UPDC32(c, crc);
  878. X    }
  879. X    zperr("Data subpacket too long");
  880. X    return ERROR;
  881. X}
  882. X
  883. X
  884. X/*
  885. X * Read a ZMODEM header to hdr, either binary or hex.
  886. X *  eflag controls local display of non zmodem characters:
  887. X *    0:  no display
  888. X *    1:  display printing characters only
  889. X *    2:  display all non ZMODEM characters
  890. X *  On success, set Zmodem to 1, set Rxpos and return type of header.
  891. X *   Otherwise return negative on error.
  892. X *   Return ERROR instantly if ZCRCW sequence, for fast error recovery.
  893. X */
  894. Xzgethdr(hdr, eflag)
  895. Xchar *hdr;
  896. X{
  897. X    register c, n, cancount;
  898. X
  899. X    n = Zrwindow + Baudrate;    /* Max bytes before start of frame */
  900. X    Rxframeind = Rxtype = 0;
  901. X
  902. Xstartover:
  903. X    cancount = 5;
  904. Xagain:
  905. X    /* Return immediate ERROR if ZCRCW sequence seen */
  906. X    switch (c = readline(Rxtimeout)) {
  907. X    case RCDO:
  908. X    case TIMEOUT:
  909. X        goto fifi;
  910. X    case CAN:
  911. Xgotcan:
  912. X        if (--cancount <= 0) {
  913. X            c = ZCAN; goto fifi;
  914. X        }
  915. X        switch (c = readline(1)) {
  916. X        case TIMEOUT:
  917. X            goto again;
  918. X        case ZCRCW:
  919. X            c = ERROR;
  920. X        /* **** FALL THRU TO **** */
  921. X        case RCDO:
  922. X            goto fifi;
  923. X        default:
  924. X            break;
  925. X        case CAN:
  926. X            if (--cancount <= 0) {
  927. X                c = ZCAN; goto fifi;
  928. X            }
  929. X            goto again;
  930. X        }
  931. X    /* **** FALL THRU TO **** */
  932. X    default:
  933. Xagn2:
  934. X        if ( --n == 0) {
  935. X            zperr("Garbage count exceeded");
  936. X            return(ERROR);
  937. X        }
  938. X        if (eflag && ((c &= 0177) & 0140))
  939. X            bttyout(c);
  940. X        else if (eflag > 1)
  941. X            bttyout(c);
  942. X        goto startover;
  943. X    case ZPAD|0200:     /* This is what we want. */
  944. X    case ZPAD:        /* This is what we want. */
  945. X        break;
  946. X    }
  947. X    cancount = 5;
  948. Xsplat:
  949. X    switch (c = noxrd7()) {
  950. X    case ZPAD:
  951. X        goto splat;
  952. X    case RCDO:
  953. X    case TIMEOUT:
  954. X        goto fifi;
  955. X    default:
  956. X        goto agn2;
  957. X    case ZDLE:        /* This is what we want. */
  958. X        break;
  959. X    }
  960. X
  961. X    switch (c = noxrd7()) {
  962. X    case RCDO:
  963. X    case TIMEOUT:
  964. X        goto fifi;
  965. X    case ZBIN:
  966. X        Rxframeind = ZBIN;  Crc32 = FALSE;
  967. X        c =  zrbhdr(hdr);
  968. X        break;
  969. X    case ZBIN32:
  970. X        Crc32 = Rxframeind = ZBIN32;
  971. X        c =  zrbhdr32(hdr);
  972. X        break;
  973. X    case ZHEX:
  974. X        Rxframeind = ZHEX;  Crc32 = FALSE;
  975. X        c =  zrhhdr(hdr);
  976. X        break;
  977. X    case CAN:
  978. X        goto gotcan;
  979. X    default:
  980. X        goto agn2;
  981. X    }
  982. X    Rxpos = hdr[ZP3] & 0377;
  983. X    Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377);
  984. X    Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377);
  985. X    Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377);
  986. Xfifi:
  987. X    switch (c) {
  988. X    case GOTCAN:
  989. X        c = ZCAN;
  990. X    /* **** FALL THRU TO **** */
  991. X    case ZNAK:
  992. X    case ZCAN:
  993. X    case ERROR:
  994. X    case TIMEOUT:
  995. X    case RCDO:
  996. X        zperr("Got %s", frametypes[c+FTOFFSET]);
  997. X    /* **** FALL THRU TO **** */
  998. X    default:
  999. X        if (c >= -3 && c <= FRTYPES)
  1000. X            vfile("zgethdr: %s %lx", frametypes[c+FTOFFSET], Rxpos);
  1001. X        else
  1002. X            vfile("zgethdr: %d %lx", c, Rxpos);
  1003. X    }
  1004. X    return c;
  1005. X}
  1006. X
  1007. X/* Receive a binary style header (type and position) */
  1008. Xzrbhdr(hdr)
  1009. Xregister char *hdr;
  1010. X{
  1011. X    register c, n;
  1012. X    register unsigned short crc;
  1013. X
  1014. X    if ((c = zdlread()) & ~0377)
  1015. X        return c;
  1016. X    Rxtype = c;
  1017. X    crc = updcrc(c, 0);
  1018. X
  1019. X    for (n=4; --n >= 0; ++hdr) {
  1020. X        if ((c = zdlread()) & ~0377)
  1021. X            return c;
  1022. X        crc = updcrc(c, crc);
  1023. X        *hdr = c;
  1024. X    }
  1025. X    if ((c = zdlread()) & ~0377)
  1026. X        return c;
  1027. X    crc = updcrc(c, crc);
  1028. X    if ((c = zdlread()) & ~0377)
  1029. X        return c;
  1030. X    crc = updcrc(c, crc);
  1031. X    if (crc & 0xFFFF) {
  1032. X        zperr("Bad Header CRC"); return ERROR;
  1033. X    }
  1034. X    Zmodem = 1;
  1035. X    return Rxtype;
  1036. X}
  1037. X
  1038. X/* Receive a binary style header (type and position) with 32 bit FCS */
  1039. Xzrbhdr32(hdr)
  1040. Xregister char *hdr;
  1041. X{
  1042. X    register c, n;
  1043. X    register UNSL long crc;
  1044. X
  1045. X    if ((c = zdlread()) & ~0377)
  1046. X        return c;
  1047. X    Rxtype = c;
  1048. X    crc = 0xFFFFFFFFL; crc = UPDC32(c, crc);
  1049. X#ifdef DEBUGZ
  1050. X    vfile("zrbhdr32 c=%X  crc=%lX", c, crc);
  1051. X#endif
  1052. X
  1053. X    for (n=4; --n >= 0; ++hdr) {
  1054. X        if ((c = zdlread()) & ~0377)
  1055. X            return c;
  1056. X        crc = UPDC32(c, crc);
  1057. X        *hdr = c;
  1058. X#ifdef DEBUGZ
  1059. X        vfile("zrbhdr32 c=%X  crc=%lX", c, crc);
  1060. X#endif
  1061. X    }
  1062. X    for (n=4; --n >= 0;) {
  1063. X        if ((c = zdlread()) & ~0377)
  1064. X            return c;
  1065. X        crc = UPDC32(c, crc);
  1066. X#ifdef DEBUGZ
  1067. X        vfile("zrbhdr32 c=%X  crc=%lX", c, crc);
  1068. X#endif
  1069. X    }
  1070. X    if (crc != 0xDEBB20E3) {
  1071. X        zperr("Bad Header CRC"); return ERROR;
  1072. X    }
  1073. X    Zmodem = 1;
  1074. X    return Rxtype;
  1075. X}
  1076. X
  1077. X
  1078. X/* Receive a hex style header (type and position) */
  1079. Xzrhhdr(hdr)
  1080. Xchar *hdr;
  1081. X{
  1082. X    register c;
  1083. X    register unsigned short crc;
  1084. X    register n;
  1085. X
  1086. X    if ((c = zgethex()) < 0)
  1087. X        return c;
  1088. X    Rxtype = c;
  1089. X    crc = updcrc(c, 0);
  1090. X
  1091. X    for (n=4; --n >= 0; ++hdr) {
  1092. X        if ((c = zgethex()) < 0)
  1093. X            return c;
  1094. X        crc = updcrc(c, crc);
  1095. X        *hdr = c;
  1096. X    }
  1097. X    if ((c = zgethex()) < 0)
  1098. X        return c;
  1099. X    crc = updcrc(c, crc);
  1100. X    if ((c = zgethex()) < 0)
  1101. X        return c;
  1102. X    crc = updcrc(c, crc);
  1103. X    if (crc & 0xFFFF) {
  1104. X        zperr("Bad Header CRC"); return ERROR;
  1105. X    }
  1106. X    if (readline(1) == '\r')        /* Throw away possible cr/lf */
  1107. X        readline(1);
  1108. X    Zmodem = 1; return Rxtype;
  1109. X}
  1110. X
  1111. X/* Send a byte as two hex digits */
  1112. Xzputhex(c)
  1113. Xregister c;
  1114. X{
  1115. X    static char    digits[]    = "0123456789abcdef";
  1116. X
  1117. X    if (Verbose>8)
  1118. X        vfile("zputhex: %02X", c);
  1119. X    sendline(digits[(c&0xF0)>>4]);
  1120. X    sendline(digits[(c)&0xF]);
  1121. X}
  1122. X
  1123. X/*
  1124. X * Send character c with ZMODEM escape sequence encoding.
  1125. X *  Escape XON, XOFF. Escape CR following @ (Telenet net escape)
  1126. X */
  1127. Xzsendline(c)
  1128. Xregister c;
  1129. X{
  1130. X    static lastsent;
  1131. X
  1132. X    switch (c &= 0377) {
  1133. X    case ZDLE:
  1134. X        xsendline(ZDLE);
  1135. X        xsendline (lastsent = (c ^= 0100));
  1136. X        break;
  1137. X    case 015:
  1138. X    case 0215:
  1139. X        if (!Zctlesc && (lastsent & 0177) != '@')
  1140. X            goto sendit;
  1141. X    /* **** FALL THRU TO **** */
  1142. X    case 020:
  1143. X    case 021:
  1144. X    case 023:
  1145. X    case 0220:
  1146. X    case 0221:
  1147. X    case 0223:
  1148. X        xsendline(ZDLE);
  1149. X        c ^= 0100;
  1150. Xsendit:
  1151. X        xsendline(lastsent = c);
  1152. X        break;
  1153. X    default:
  1154. X        if (Zctlesc && ! (c & 0140)) {
  1155. X            xsendline(ZDLE);
  1156. X            c ^= 0100;
  1157. X        }
  1158. X        xsendline(lastsent = c);
  1159. X    }
  1160. X}
  1161. X
  1162. X/* Decode two lower case hex digits into an 8 bit byte value */
  1163. Xzgethex()
  1164. X{
  1165. X    register c;
  1166. X
  1167. X    c = zgeth1();
  1168. X    if (Verbose>8)
  1169. X        vfile("zgethex: %02X", c);
  1170. X    return c;
  1171. X}
  1172. Xzgeth1()
  1173. X{
  1174. X    register c, n;
  1175. X
  1176. X    if ((c = noxrd7()) < 0)
  1177. X        return c;
  1178. X    n = c - '0';
  1179. X    if (n > 9)
  1180. X        n -= ('a' - ':');
  1181. X    if (n & ~0xF)
  1182. X        return ERROR;
  1183. X    if ((c = noxrd7()) < 0)
  1184. X        return c;
  1185. X    c -= '0';
  1186. X    if (c > 9)
  1187. X        c -= ('a' - ':');
  1188. X    if (c & ~0xF)
  1189. X        return ERROR;
  1190. X    c += (n<<4);
  1191. X    return c;
  1192. X}
  1193. X
  1194. X/*
  1195. X * Read a byte, checking for ZMODEM escape encoding
  1196. X *  including CAN*5 which represents a quick abort
  1197. X */
  1198. Xzdlread()
  1199. X{
  1200. X    register c;
  1201. X
  1202. Xagain:
  1203. X    switch (c = readline(Rxtimeout)) {
  1204. X    case ZDLE:
  1205. X        break;
  1206. X    case 023:
  1207. X    case 0223:
  1208. X    case 021:
  1209. X    case 0221:
  1210. X        goto again;
  1211. X    default:
  1212. X        if (Zctlesc && !(c & 0140)) {
  1213. X            goto again;
  1214. X        }
  1215. X        return c;
  1216. X    }
  1217. Xagain2:
  1218. X    if ((c = readline(Rxtimeout)) < 0)
  1219. X        return c;
  1220. X    if (c == CAN && (c = readline(Rxtimeout)) < 0)
  1221. X        return c;
  1222. X    if (c == CAN && (c = readline(Rxtimeout)) < 0)
  1223. X        return c;
  1224. X    if (c == CAN && (c = readline(Rxtimeout)) < 0)
  1225. X        return c;
  1226. X    switch (c) {
  1227. X    case CAN:
  1228. X        return GOTCAN;
  1229. X    case ZCRCE:
  1230. X    case ZCRCG:
  1231. X    case ZCRCQ:
  1232. X    case ZCRCW:
  1233. X        return (c | GOTOR);
  1234. X    case ZRUB0:
  1235. X        return 0177;
  1236. X    case ZRUB1:
  1237. X        return 0377;
  1238. X    case 023:
  1239. X    case 0223:
  1240. X    case 021:
  1241. X    case 0221:
  1242. X        goto again2;
  1243. X    default:
  1244. X        if (Zctlesc && ! (c & 0140)) {
  1245. X            goto again2;
  1246. X        }
  1247. X        if ((c & 0140) ==  0100)
  1248. X            return (c ^ 0100);
  1249. X        break;
  1250. X    }
  1251. X    zperr("Bad escape sequence %x", c);
  1252. X    return ERROR;
  1253. X}
  1254. X
  1255. X/*
  1256. X * Read a character from the modem line with timeout.
  1257. X *  Eat parity, XON and XOFF characters.
  1258. X */
  1259. Xnoxrd7()
  1260. X{
  1261. X    register c;
  1262. X
  1263. X    for (;;) {
  1264. X        if ((c = readline(Rxtimeout)) < 0)
  1265. X            return c;
  1266. X        switch (c &= 0177) {
  1267. X        case XON:
  1268. X        case XOFF:
  1269. X            continue;
  1270. X        default:
  1271. X            if (Zctlesc && !(c & 0140))
  1272. X                continue;
  1273. X        case '\r':
  1274. X        case '\n':
  1275. X        case ZDLE:
  1276. X            return c;
  1277. X        }
  1278. X    }
  1279. X}
  1280. X
  1281. X/* Store long integer pos in Txhdr */
  1282. Xstohdr(pos)
  1283. Xlong pos;
  1284. X{
  1285. X    Txhdr[ZP0] = pos;
  1286. X    Txhdr[ZP1] = pos>>8;
  1287. X    Txhdr[ZP2] = pos>>16;
  1288. X    Txhdr[ZP3] = pos>>24;
  1289. X}
  1290. X
  1291. X/* Recover a long integer from a header */
  1292. Xlong
  1293. Xrclhdr(hdr)
  1294. Xregister char *hdr;
  1295. X{
  1296. X    register long l;
  1297. X
  1298. X    l = (hdr[ZP3] & 0377);
  1299. X    l = (l << 8) | (hdr[ZP2] & 0377);
  1300. X    l = (l << 8) | (hdr[ZP1] & 0377);
  1301. X    l = (l << 8) | (hdr[ZP0] & 0377);
  1302. X    return l;
  1303. X}
  1304. X
  1305. X/* End of zm.c */
  1306. SHAR_EOF
  1307. echo "extracting Zmodem/sz.c"
  1308. sed 's/^X//' << \SHAR_EOF > Zmodem/sz.c
  1309. X#define VERSION "sz 1.36 08-31-87"
  1310. X#define PUBDIR "/usr/spool/uucppublic"
  1311. X
  1312. X/*% cc -M0 -Ox -K -i -DNFGVMIN -DREADCHECK sz.c -lx -o sz; size sz
  1313. X *
  1314. X * sz.c By Chuck Forsberg
  1315. X *
  1316. X * Amiga version by Frank Harper using Aztec C 3.4b
  1317. X *
  1318. X *    cc +L sz.c;cc +L SerIO.c;cc +L term.c;ln sz.o SerIO.o term.o -lc32
  1319. X *    or just use the makefile
  1320. X *
  1321. X * See Amiga.doc for more details on Amiga version
  1322. X *
  1323. X *    cc -O sz.c -o sz        USG (SYS III/V) Unix
  1324. X *    cc -O -DSVR2 sz.c -o sz     Sys V Release 2 with non-blocking input
  1325. X *                    Define to allow reverse channel checking
  1326. X *    cc -O -DV7  sz.c -o sz        Unix Version 7, 2.8 - 4.3 BSD
  1327. X *
  1328. X *    cc -O -K -i -DNFGVMIN -DREADCHECK sz.c -lx -o sz    Xenix
  1329. X *
  1330. X *    ln sz sb            **** All versions ****
  1331. X *    ln sz sx            **** All versions ****
  1332. X *
  1333. X *
  1334. X *  ******* Some systems (Venix, Coherent, Regulus) do not *******
  1335. X *  ******* support tty raw mode read(2) identically to    *******
  1336. X *  ******* Unix. ONEREAD must be defined to force one       *******
  1337. X *  ******* character reads for these systems.           *******
  1338. X *
  1339. X * A program for Unix to send files and commands to computers running
  1340. X *  Professional-YAM, PowerCom, YAM, IMP, or programs supporting Y/XMODEM.
  1341. X *
  1342. X *  Sz uses buffered I/O to greatly reduce CPU time compared to UMODEM.
  1343. X *
  1344. X *  USG UNIX (3.0) ioctl conventions courtesy Jeff Martin
  1345. X *
  1346. X * 1.34 implements tx backchannel garbage count and ZCRCW after ZRPOS
  1347. X * in accordance with the 7-31-87 ZMODEM Protocol Description
  1348. X */
  1349. X
  1350. X
  1351. Xchar *substr(), *getenv();
  1352. X
  1353. X#define PATHLEN 256
  1354. X#define OK 0
  1355. X#define ERROR (-1)
  1356. X
  1357. X#ifdef AMIGA
  1358. X#include <stdio.h>
  1359. X#include <ctype.h>
  1360. X#include <stat.h>
  1361. X#include <devices/timer.h>
  1362. X#include <devices/serial.h>
  1363. X#include <libraries/dos.h>
  1364. X#include "intuition/intuition.h"
  1365. X
  1366. X#define LOGFILE "szlog"
  1367. X#define READCHECK
  1368. X
  1369. Xvoid *malloc();
  1370. Xvoid *OpenLibrary();
  1371. Xstruct Window *OpenWindow();
  1372. X
  1373. Xstruct IntuitionBase *IntuitionBase;
  1374. Xstruct NewWindow nw = {
  1375. X   0, 0,         /* start position            */
  1376. X   640, 120,         /* width, height            */
  1377. X   -1, -1,         /* detail pen, block pen        */
  1378. X   CLOSEWINDOW,           /* IDCMP flags             */
  1379. X   ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING | WINDOWCLOSE
  1380. X   | NOCAREREFRESH, /* window flags               */
  1381. X   NULL,         /* pointer to first user gadget    */
  1382. X   NULL,         /* pointer to user checkmark    */
  1383. X   (UBYTE *)"Sz",             /* window title                    */
  1384. X   NULL,         /* pointer to screen    (later)    */
  1385. X   NULL,         /* pointer to superbitmap        */
  1386. X   50,40,-1,-1,  /* sizing limits min and max        */
  1387. X   WBENCHSCREEN      /* type of screen in which to open */
  1388. X   };
  1389. X
  1390. Xint Lleft;
  1391. Xint InitSer = FALSE;
  1392. Xint gmt_diff_set=FALSE; /* Has GMT offset been set? */
  1393. Xint gmt_diff;        /* Local time offset from GMT time */
  1394. Xint SendProtect=TRUE;    /* send file protection bits? */
  1395. Xint Term=FALSE;     /* Use Terminal mode ? */
  1396. Xint WaitC=TRUE;     /* Wait for confirmation before closing window?*/
  1397. Xstruct IOStdReq *ConWriteReq, *ConReadReq;
  1398. Xstruct Window *Win;
  1399. Xstruct MsgPort    *ConReadPort,*ConWritePort;
  1400. Xint WinOutPut;
  1401. Xint FullDuplex=TRUE;
  1402. XULONG  InSerSigMask, OutSerSigMask;
  1403. XUBYTE  SerOpen;
  1404. XULONG  IOTimeSigMask;
  1405. Xstruct IOExtSer *InSer, *OutSer;
  1406. Xstruct MsgPort    *InSerPort, *OutSerPort;
  1407. Xstruct timerequest *IOTime;
  1408. Xstruct MsgPort *TimerPort;
  1409. X#else
  1410. X#define LOGFILE "/tmp/szlog"
  1411. X
  1412. X#include <stdio.h>
  1413. X#include <signal.h>
  1414. X#include <setjmp.h>
  1415. X#include <ctype.h>
  1416. X
  1417. X#define FALSE 0
  1418. X#define TRUE 1
  1419. X#endif /* AMIGA */
  1420. X
  1421. X#define HOWMANY 2
  1422. Xint Zmodem=0;        /* ZMODEM protocol requested */
  1423. Xunsigned Baudrate;
  1424. Xunsigned Txwindow;    /* Control the size of the transmitted window */
  1425. Xunsigned Txwspac;    /* Spacing between zcrcq requests */
  1426. Xunsigned Txwcnt;    /* Counter used to space ack requests */
  1427. Xlong Lrxpos;        /* Receiver's last reported offset */
  1428. Xint Fromcu = 0;     /* Were called from cu or yam */
  1429. Xint errors;
  1430. X
  1431. X/*
  1432. X * Attention string to be executed by receiver to interrupt streaming data
  1433. X *  when an error is detected.    A pause (0336) may be needed before the
  1434. X *  ^C (03) or after it.
  1435. X */
  1436. X#ifdef READCHECK
  1437. Xchar Myattn[] = { 0 };
  1438. X#else
  1439. X#ifdef USG
  1440. Xchar Myattn[] = { 03, 0336, 0 };
  1441. X#else
  1442. Xchar Myattn[] = { 0 };
  1443. X#endif
  1444. X#endif
  1445. X
  1446. XFILE *in;
  1447. X
  1448. X/* Ward Christensen / CP/M parameters - Don't change these! */
  1449. X#define ENQ 005
  1450. X#define CAN ('X'&037)
  1451. X#define XOFF ('s'&037)
  1452. X#define XON ('q'&037)
  1453. X#define SOH 1
  1454. X#define STX 2
  1455. X#define EOT 4
  1456. X#define ACK 6
  1457. X#define NAK 025
  1458. X#define CPMEOF 032
  1459. X#define WANTCRC 0103    /* send C not NAK to get crc not checksum */
  1460. X#define WANTG 0107    /* Send G not NAK to get nonstop batch xmsn */
  1461. X#define TIMEOUT (-2)
  1462. X#define RCDO (-3)
  1463. X#define RETRYMAX 10
  1464. X#define SECSIZ 128    /* cp/m's Magic Number record size */
  1465. X#define KSIZE 1024
  1466. X
  1467. Xchar Lastrx;
  1468. Xchar Crcflg;
  1469. Xint Wcsmask=0377;
  1470. Xint Verbose=0;
  1471. Xint Modem2=0;        /* XMODEM Protocol - don't send pathnames */
  1472. Xint Restricted=0;    /* restricted; no /.. or ../ in filenames */
  1473. Xint Quiet=0;        /* overrides logic that would otherwise set verbose */
  1474. Xint Ascii=0;        /* Add CR's for brain damaged programs */
  1475. Xint Fullname=0;     /* transmit full pathname */
  1476. Xint Unlinkafter=0;    /* Unlink file after it is sent */
  1477. Xint Dottoslash=0;    /* Change foo.bar.baz to foo/bar/baz */
  1478. Xint firstsec;
  1479. Xint errcnt=0;        /* number of files unreadable */
  1480. Xint blklen=SECSIZ;        /* length of transmitted records */
  1481. Xint Optiong;        /* Let it rip no wait for sector ACK's */
  1482. Xint Noeofseen;
  1483. Xint Totsecs;        /* total number of sectors this file */
  1484. Xchar txbuf[KSIZE];
  1485. Xint Filcnt=0;        /* count of number of files opened */
  1486. Xint Lfseen=0;
  1487. Xunsigned Rxbuflen = 16384;    /* Receiver's max buffer length */
  1488. Xint Tframlen = 0;    /* Override for tx frame length */
  1489. Xint blkopt=0;        /* Override value for zmodem blklen */
  1490. Xint Rxflags = 0;
  1491. Xlong bytcnt;
  1492. Xint Wantfcs32 = TRUE;    /* want to send 32 bit FCS */
  1493. Xchar Lzconv;    /* Local ZMODEM file conversion request */
  1494. Xchar Lzmanag;    /* Local ZMODEM file management request */
  1495. Xint Lskipnocor;
  1496. Xchar Lztrans;
  1497. Xchar zconv;        /* ZMODEM file conversion request */
  1498. Xchar zmanag;        /* ZMODEM file management request */
  1499. Xchar ztrans;        /* ZMODEM file transport request */
  1500. Xint Command;        /* Send a command, then exit. */
  1501. Xchar *Cmdstr;        /* Pointer to the command string */
  1502. Xint Cmdtries = 11;
  1503. Xint Cmdack1;        /* Rx ACKs command, then do it */
  1504. Xint Exitcode = 0;
  1505. X#ifndef AMIGA
  1506. Xint Testattn;        /* Force receiver to send Attn, etc with qbf. */
  1507. X#endif
  1508. Xchar *qbf="The quick brown fox jumped over the lazy dog's back 1234567890\r\n";
  1509. Xlong Lastread;        /* Beginning offset of last buffer read */
  1510. Xint Lastn;        /* Count of last buffer read or -1 */
  1511. Xint Dontread;        /* Don't read the buffer, it's still there */
  1512. Xlong Lastsync;        /* Last offset to which we got a ZRPOS */
  1513. Xint Beenhereb4;     /* How many times we've been ZRPOS'd same place */
  1514. X
  1515. X#ifndef AMIGA        /* No setjmp's in amiga version */
  1516. Xjmp_buf tohere;     /* For the interrupt on RX timeout */
  1517. Xjmp_buf intrjmp;    /* For the interrupt on RX CAN */
  1518. X#endif
  1519. X
  1520. X#ifndef AMIGA
  1521. X/* called by signal interrupt or terminate to clean things up */
  1522. Xbibi(n)
  1523. X{
  1524. X    canit(); fflush(stdout); mode(0);
  1525. X    fprintf(stderr, "sz: caught signal %d; exiting\n", n);
  1526. X    if (n == SIGQUIT)
  1527. X        abort();
  1528. X    exit(128+n);
  1529. X}
  1530. X
  1531. X/* Called when Zmodem gets an interrupt (^X) */
  1532. Xonintr()
  1533. X{
  1534. X    signal(SIGINT, SIG_IGN);
  1535. X    longjmp(intrjmp, -1);
  1536. X}
  1537. X
  1538. X#define sendline(c) putchar(c & Wcsmask)
  1539. X
  1540. X#define xsendline(c) putchar(c)
  1541. X
  1542. X#else /* AMIGA */
  1543. X
  1544. XWaitbibi(n)
  1545. Xint n;
  1546. X{
  1547. X    ConPutChar(ConWriteReq,7);
  1548. X    ConPutStr(ConWriteReq,"\nsz: Transfer aborted");
  1549. X    if( WaitC ) WaitClose();
  1550. X    bibi(n);
  1551. X}
  1552. X
  1553. XWaitClose()
  1554. X{
  1555. X ULONG IntuiMask;
  1556. X
  1557. X    IntuiMask = 1 << (Win->UserPort->mp_SigBit);
  1558. X    while(!CheckQuit()) Wait(IntuiMask);
  1559. X}
  1560. X
  1561. Xbibi(n)
  1562. X{
  1563. X    canit(); mode(0);
  1564. X    if (in) fclose(in);
  1565. X    CleanUp();
  1566. X    exit(128+n);
  1567. X}
  1568. X
  1569. XAmigaInit()
  1570. X{
  1571. X    IntuitionBase = (struct IntuitionBase *)
  1572. X            OpenLibrary("intuition.library", 33L);
  1573. X    if (IntuitionBase == NULL) {
  1574. X    puts("Unable to open 1.2 or higher intuition.library");
  1575. X    exit(1);
  1576. X    }
  1577. X    Win = OpenWindow(&nw);
  1578. X    if ( Win == NULL ) {
  1579. X    puts("Unable to open window");
  1580. X    CleanUp();
  1581. X    exit(1);
  1582. X    }
  1583. X    WinOutPut=TRUE;
  1584. X    if( OpenConsole(&ConWriteReq,&ConReadReq,Win)) {
  1585. X    puts("Couldn't open console");
  1586. X    CleanUp();
  1587. X    exit(1);
  1588. X    }
  1589. X}
  1590. X
  1591. XCleanUp()
  1592. X{
  1593. X    CloseConsole(ConReadReq,ConWriteReq);
  1594. X    if( Win )         CloseWindow(Win);
  1595. X    if(IntuitionBase) CloseLibrary(IntuitionBase);
  1596. X}
  1597. X
  1598. X#define sendline(c) xsendline(c & Wcsmask)
  1599. X
  1600. Xint nchars=0;
  1601. Xint BufferSize=128;
  1602. XUBYTE *OutBuf,*Next;
  1603. X
  1604. Xxsendline(c)
  1605. Xint c;
  1606. X{
  1607. X    *Next++=c;
  1608. X    if(++nchars==BufferSize) flushmo();
  1609. X}
  1610. X
  1611. X#undef fflush()
  1612. X
  1613. X /* Zmodem uses fflush to flush any pending output to the modem */
  1614. Xfflush(f)
  1615. XFILE *f;
  1616. X{
  1617. X
  1618. X    LWriteSer(OutBuf,nchars);
  1619. X    nchars=0;
  1620. X    Next=OutBuf;
  1621. X}
  1622. X
  1623. Xfprintf(f,s,a1,a2,a3,a4)
  1624. XFILE *f;
  1625. Xchar *s;
  1626. Xchar *a1,*a2,*a3,*a4;
  1627. X{
  1628. X char buf[256];
  1629. X
  1630. X sprintf(buf,s,a1,a2,a3,a4);
  1631. X if( WinOutPut ) ConPutStr(ConWriteReq,buf);
  1632. X else fputs(buf,f);
  1633. X}
  1634. X#endif /* AMIGA */
  1635. X
  1636. Xflushmo()
  1637. X{
  1638. X    fflush(stdout);
  1639. X}
  1640. X
  1641. Xint Zctlesc;    /* Encode control characters */
  1642. Xint Nozmodem = 0;    /* If invoked as "sb" */
  1643. Xchar *Progname = "sz";
  1644. Xint Zrwindow = 1400;    /* RX window size (controls garbage count) */
  1645. X#include "rbsb.c"       /* most of the system dependent stuff here */
  1646. X#include "zm.c"
  1647. X
  1648. X
  1649. Xmain(argc, argv)
  1650. Xchar *argv[];
  1651. X{
  1652. X    register char *cp;
  1653. X    register npats;
  1654. X    int agcnt; char **agcv;
  1655. X    char **patts;
  1656. X#ifndef AMIGA
  1657. X    static char xXbuf[BUFSIZ];
  1658. X#endif
  1659. X    if ((cp = getenv("ZNULLS")) && *cp)
  1660. X        Znulls = atoi(cp);
  1661. X    if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh")))
  1662. X        Restricted=TRUE;
  1663. X    chkinvok(argv[0]);
  1664. X
  1665. X    Rxtimeout = 600;
  1666. X    npats=0;
  1667. X#ifdef AMIGA
  1668. X    AmigaInit();
  1669. X#endif
  1670. X    if (argc<2)
  1671. X        usage();
  1672. X#ifndef AMIGA
  1673. X    setbuf(stdout, xXbuf);
  1674. X#endif
  1675. X    while (--argc) {
  1676. X        cp = *++argv;
  1677. X        if (*cp++ == '-' && *cp) {
  1678. X            while ( *cp) {
  1679. X                switch(*cp++) {
  1680. X                case '+':
  1681. X                    Lzmanag = ZMAPND; break;
  1682. X#ifndef AMIGA
  1683. X                case '1':
  1684. X                    iofd = 1; break;
  1685. X#ifdef CSTOPB
  1686. X                case '2':
  1687. X                    Twostop = TRUE; break;
  1688. X#endif
  1689. X#endif
  1690. X                case '7':
  1691. X                    Wcsmask=0177; break;
  1692. X                case 'a':
  1693. X                    Lzconv = ZCNL;
  1694. X                    Ascii = TRUE; break;
  1695. X                case 'b':
  1696. X                    Lzconv = ZCBIN; break;
  1697. X#ifdef AMIGA
  1698. X                case 'B':
  1699. X                    Nozmodem = TRUE; blklen=KSIZE; break;
  1700. X#endif
  1701. X                case 'C':
  1702. X                    if (--argc < 1) {
  1703. X                        usage();
  1704. X                    }
  1705. X                    Cmdtries = atoi(*++argv);
  1706. X                    break;
  1707. X#ifdef AMIGA
  1708. X                case 'I':
  1709. X                    InitSer = TRUE; break;
  1710. X#endif
  1711. X                case 'i':
  1712. X                    Cmdack1 = ZCACK1;
  1713. X                    /* **** FALL THROUGH TO **** */
  1714. X                case 'c':
  1715. X                    if (--argc != 1) {
  1716. X                        usage();
  1717. X                    }
  1718. X                    Command = TRUE;
  1719. X                    Cmdstr = *++argv;
  1720. X                    break;
  1721. X                case 'd':
  1722. X                    ++Dottoslash;
  1723. X                    /* **** FALL THROUGH TO **** */
  1724. X                case 'f':
  1725. X                    Fullname=TRUE; break;
  1726. X                case 'e':
  1727. X                    Zctlesc = 1; break;
  1728. X#ifdef AMIGA
  1729. X                case 'h':
  1730. X                    FullDuplex = FALSE; break;
  1731. X#endif
  1732. X                case 'k':
  1733. X                    blklen=KSIZE; break;
  1734. X                case 'L':
  1735. X                    if (--argc < 1) {
  1736. X                        usage();
  1737. X                    }
  1738. X                    blkopt = atoi(*++argv);
  1739. X                    if (blkopt<24 || blkopt>1024)
  1740. X                        usage();
  1741. X                    break;
  1742. X                case 'l':
  1743. X                    if (--argc < 1) {
  1744. X                        usage();
  1745. X                    }
  1746. X                    Tframlen = atoi(*++argv);
  1747. X                    if (Tframlen<32 || Tframlen>1024)
  1748. X                        usage();
  1749. X                    break;
  1750. X#ifdef AMIGA
  1751. X                case 'm':
  1752. X                    SendProtect = FALSE; break;
  1753. X#endif
  1754. X                case 'N':
  1755. X                    Lzmanag = ZMNEWL;  break;
  1756. X                case 'n':
  1757. X                    Lzmanag = ZMNEW;  break;
  1758. X                case 'o':
  1759. X                    Wantfcs32 = FALSE; break;
  1760. X                case 'p':
  1761. X                    Lzmanag = ZMPROT;  break;
  1762. X                case 'r':
  1763. X                    Lzconv = ZCRESUM;
  1764. X                case 'q':
  1765. X                    Quiet=TRUE; Verbose=0; break;
  1766. X#ifdef AMIGA
  1767. X                case 'Q':
  1768. X                    WaitC = FALSE; break;
  1769. X#endif
  1770. X                case 't':
  1771. X                    if (--argc < 1) {
  1772. X                        usage();
  1773. X                    }
  1774. X                    Rxtimeout = atoi(*++argv);
  1775. X                    if (Rxtimeout<10 || Rxtimeout>1000)
  1776. X                        usage();
  1777. X                    break;
  1778. X                case 'T':
  1779. X#ifndef AMIGA
  1780. X                    Testattn = TRUE; break;
  1781. X#else
  1782. X                    Term=TRUE; break;
  1783. X#endif
  1784. X                case 'u':
  1785. X                    ++Unlinkafter; break;
  1786. X                case 'v':
  1787. X                    ++Verbose; break;
  1788. X                case 'w':
  1789. X                    if (--argc < 1) {
  1790. X                        usage();
  1791. X                    }
  1792. X                    Txwindow = atoi(*++argv);
  1793. X                    if (Txwindow < 256)
  1794. X                        Txwindow = 256;
  1795. X                    Txwindow = (Txwindow/64) * 64;
  1796. X                    Txwspac = Txwindow/4;
  1797. X                    if (blkopt > Txwspac
  1798. X                     || (!blkopt && Txwspac < 1024))
  1799. X                        blkopt = Txwspac;
  1800. X                    break;
  1801. X                case 'X':
  1802. X                    ++Modem2; break;
  1803. X                case 'Y':
  1804. X                    Lskipnocor = TRUE;
  1805. X                    /* **** FALLL THROUGH TO **** */
  1806. X                case 'y':
  1807. X                    Lzmanag = ZMCLOB; break;
  1808. X                default:
  1809. X                    usage();
  1810. X                }
  1811. X            }
  1812. X        }
  1813. X        else if ( !npats && argc>0) {
  1814. X            if (argv[0][0]) {
  1815. X                npats=argc;
  1816. X                patts=argv;
  1817. X#ifndef AMIGA
  1818. X                if ( !strcmp(*patts, "-"))
  1819. X                    iofd = 1;
  1820. X#endif
  1821. X            }
  1822. X        }
  1823. X    }
  1824. X    if (npats < 1 && !Command)
  1825. X            usage();
  1826. X#ifdef AMIGA
  1827. X    if( mode(1)==ERROR) {
  1828. X        fprintf(stderr,"Couldn't initialize serial port\n");
  1829. X        Waitbibi(1);
  1830. X    }
  1831. X    if (Term) {
  1832. X        fprintf(stderr,"Entering terminal mode, click on close box when ready to start file transfer\n");
  1833. X        term();
  1834. X    }
  1835. X#endif
  1836. X    if (Verbose) {
  1837. X        if (freopen(LOGFILE, "a", stderr)==NULL) {
  1838. X            printf("Can't open log file %s\n",LOGFILE);
  1839. X            exit(0200);
  1840. X        }
  1841. X        setbuf(stderr, NULL);
  1842. X#ifdef AMIGA
  1843. X        WinOutPut=FALSE;
  1844. X#endif
  1845. X    }
  1846. X    if ((Fromcu=from_cu()) && !Quiet) {
  1847. X        if (Verbose == 0)
  1848. X            Verbose = 2;
  1849. X    }
  1850. X
  1851. X#ifndef AMIGA
  1852. X    mode(1);
  1853. X    if (signal(SIGINT, bibi) == SIG_IGN) {
  1854. X        signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
  1855. X    } else {
  1856. X        signal(SIGINT, bibi); signal(SIGKILL, bibi);
  1857. X    }
  1858. X    if ( !Fromcu)
  1859. X        signal(SIGQUIT, SIG_IGN);
  1860. X    signal(SIGTERM, bibi);
  1861. X#endif
  1862. X    if ( !Modem2) {
  1863. X        if (!Nozmodem) {
  1864. X#ifndef AMIGA
  1865. X            printf("rz\r");  fflush(stdout);
  1866. X#else
  1867. X            LWriteSer("\rrz\r",4); /* try to fire up remote rz */
  1868. X#endif
  1869. X        }
  1870. X        if (!Command && !Quiet && Verbose != 1) {
  1871. X            fprintf(stderr, "%s: %d file%s requested:\r\n",
  1872. X             Progname, npats, npats>1?"s":"");
  1873. X            for ( agcnt=npats, agcv=patts; --agcnt>=0; ) {
  1874. X                fprintf(stderr, "%s ", *agcv++);
  1875. X            }
  1876. X            fprintf(stderr, "\r\n");
  1877. X#ifndef AMIGA /* What is that backspace doing there? */
  1878. X            printf("\r\n\bSending in Batch Mode\r\n");
  1879. X#else
  1880. X            fprintf(stderr,"\nSending in Batch Mode\n");
  1881. X#endif
  1882. X        }
  1883. X        if (!Nozmodem) {
  1884. X            stohdr(0L);
  1885. X            if (Command)
  1886. X                Txhdr[ZF0] = ZCOMMAND;
  1887. X            zshhdr(ZRQINIT, Txhdr);
  1888. X        }
  1889. X    }
  1890. X    fflush(stdout);
  1891. X
  1892. X    if (Command) {
  1893. X        if (getzrxinit()) {
  1894. X            Exitcode=0200; canit();
  1895. X        }
  1896. X        else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) {
  1897. X            Exitcode=0200; canit();
  1898. X        }
  1899. X    } else if (wcsend(npats, patts)==ERROR) {
  1900. X        Exitcode=0200;
  1901. X        canit();
  1902. X    }
  1903. X    fflush(stdout);
  1904. X#ifdef AMIGA
  1905. X    fprintf(stderr,"\n");
  1906. X    if( (errcnt!=0)| Exitcode) {
  1907. X        fprintf(stderr,"Unable to complete transfer\n");
  1908. X        ConPutChar(ConWriteReq,7);
  1909. X    }
  1910. X    else
  1911. X        fprintf(stderr,"File transfer succesful\n");
  1912. X    if (Term) {
  1913. X        fprintf(stderr,"Re-entering terminal mode. Click on close box to exit Sz.\n");
  1914. X        term();
  1915. X    }
  1916. X    else if( WaitC ) {
  1917. X        fprintf(stderr,"Click on close box to exit Sz\n");
  1918. X        WaitClose();
  1919. X    }
  1920. X    CleanUp();
  1921. X#endif
  1922. X    mode(0);
  1923. X    exit((errcnt != 0) | Exitcode);
  1924. X    /*NOTREACHED*/
  1925. X}
  1926. X
  1927. Xwcsend(argc, argp)
  1928. Xchar *argp[];
  1929. X{
  1930. X    register n;
  1931. X
  1932. X    Crcflg=FALSE;
  1933. X    firstsec=TRUE;
  1934. X    bytcnt = -1;
  1935. X    for (n=0; n<argc; ++n) {
  1936. X        Totsecs = 0;
  1937. X        if (wcs(argp[n])==ERROR)
  1938. X            return ERROR;
  1939. X    }
  1940. X    Totsecs = 0;
  1941. X    if (Filcnt==0) {        /* bitch if we couldn't open ANY files */
  1942. X        if (1) {
  1943. X            Command = TRUE;
  1944. X            Cmdstr = "echo \"sz: Can't open any requested files\"";
  1945. X            if (getnak()) {
  1946. X                Exitcode=0200; canit();
  1947. X            }
  1948. X            if (!Zmodem)
  1949. X                canit();
  1950. X            else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) {
  1951. X                Exitcode=0200; canit();
  1952. X            }
  1953. X            Exitcode = 1; return OK;
  1954. X        }
  1955. X        canit();
  1956. X        fprintf(stderr,"\r\nCan't open any requested files.\r\n");
  1957. X        return ERROR;
  1958. X    }
  1959. X    if (Zmodem)
  1960. X        saybibi();
  1961. X    else if ( !Modem2)
  1962. X        wctxpn("");
  1963. X    return OK;
  1964. X}
  1965. X
  1966. Xwcs(oname)
  1967. Xchar *oname;
  1968. X{
  1969. X    register c;
  1970. X    register char *p;
  1971. X    struct stat f;
  1972. X    char name[PATHLEN];
  1973. X
  1974. X    strcpy(name, oname);
  1975. X
  1976. X#ifndef AMIGA
  1977. X    if (Restricted) {
  1978. X        /* restrict pathnames to current tree or uucppublic */
  1979. X        if ( substr(name, "../")
  1980. X         || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
  1981. X            canit();
  1982. X            fprintf(stderr,"\r\nsz:\tSecurity Violation\r\n");
  1983. X            return ERROR;
  1984. X        }
  1985. X    }
  1986. X    if ( !strcmp(oname, "-")) {
  1987. X        if ((p = getenv("ONAME")) && *p)
  1988. X            strcpy(name, p);
  1989. X        else
  1990. X            sprintf(name, "s%d.sz",getpid());
  1991. X        in = stdin;
  1992. X    }
  1993. X    else
  1994. X#endif
  1995. X         if ((in=fopen(oname, "r"))==NULL) {
  1996. X        ++errcnt;
  1997. X        return OK;    /* pass over it, there may be others */
  1998. X    }
  1999. X    ++Noeofseen;  Lastread = 0;  Lastn = -1; Dontread = FALSE;
  2000. X
  2001. X#ifndef AMIGA
  2002. X    /* Check for directory or block special files */
  2003. X    fstat(fileno(in), &f);
  2004. X    c = f.st_mode & S_IFMT;
  2005. X    if (c == S_IFDIR || c == S_IFBLK) {
  2006. X        fclose(in);
  2007. X        return OK;
  2008. X    }
  2009. X#else
  2010. X    stat(oname, &f);
  2011. X    fprintf(stderr, "%s: File size: %lu bytes\n", oname, f.st_size);
  2012. X#endif
  2013. X    ++Filcnt;
  2014. X    switch (wctxpn(name)) {
  2015. X    case ERROR:
  2016. X        return ERROR;
  2017. X    case ZSKIP:
  2018. X        return OK;
  2019. X    }
  2020. X    if (!Zmodem && wctx(f.st_size)==ERROR)
  2021. X        return ERROR;
  2022. X    if (Unlinkafter)
  2023. X        unlink(oname);
  2024. X    return 0;
  2025. X}
  2026. X
  2027. X/*
  2028. X * generate and transmit pathname block consisting of
  2029. X *  pathname (null terminated),
  2030. X *  file length, mode time and file mode in octal
  2031. X *  as provided by the Unix fstat call.
  2032. X *  N.B.: modifies the passed name, may extend it!
  2033. X */
  2034. Xwctxpn(name)
  2035. Xchar *name;
  2036. X{
  2037. X    register char *p, *q;
  2038. X    char name2[PATHLEN];
  2039. X    struct stat f;
  2040. X#ifdef AMIGA
  2041. X    USHORT mode;
  2042. X    char *name3;
  2043. X#endif
  2044. X
  2045. X    if (Modem2) {
  2046. X#ifndef AMIGA
  2047. X        if ((in!=stdin) && *name && fstat(fileno(in), &f)!= -1) {
  2048. X#else
  2049. X        if ((in!=stdin) && *name && stat(name, &f)!= -1) {
  2050. X#endif
  2051. X            fprintf(stderr, "Sending %s, %ld blocks: ",
  2052. X              name, f.st_size>>7);
  2053. X        }
  2054. X        fprintf(stderr, "Give your local XMODEM receive command now.\r\n");
  2055. X        return OK;
  2056. X    }
  2057. X    zperr("Awaiting pathname nak for %s", *name?name:"<END>");
  2058. X    if ( !Zmodem)
  2059. X        if (getnak())
  2060. X            return ERROR;
  2061. X
  2062. X    q = (char *) 0;
  2063. X    if (Dottoslash) {               /* change . to . */
  2064. X        for (p=name; *p; ++p) {
  2065. X            if (*p == '/')
  2066. X                q = p;
  2067. X            else if (*p == '.')
  2068. X                *(q=p) = '/';
  2069. X        }
  2070. X        if (q && strlen(++q) > 8) {     /* If name>8 chars */
  2071. X            q += 8;         /*   make it .ext */
  2072. X            strcpy(name2, q);       /* save excess of name */
  2073. X            *q = '.';
  2074. X            strcpy(++q, name2);     /* add it back */
  2075. X        }
  2076. X    }
  2077. X
  2078. X#ifdef AMIGA
  2079. X    for (p = name3 = name; *p; )
  2080. X        if(*p++ == ':') {
  2081. X            name3 = p;
  2082. X            break;
  2083. X    }
  2084. X
  2085. X    for (p=name3, q=txbuf ; *p; )
  2086. X#else
  2087. X    for (p=name, q=txbuf ; *p; )
  2088. X#endif
  2089. X        if ((*q++ = *p++) == '/' && !Fullname)
  2090. X            q = txbuf;
  2091. X    *q++ = 0;
  2092. X    p=q;
  2093. X    while (q < (txbuf + KSIZE))
  2094. X        *q++ = 0;
  2095. X#ifndef AMIGA
  2096. X    if (!Ascii && (in!=stdin) && *name && fstat(fileno(in), &f)!= -1)
  2097. X        sprintf(p, "%lu %lo %o", f.st_size, f.st_mtime, f.st_mode);
  2098. X#else  /* translate AMIGA modes to UNIX modes */
  2099. X    if (!Ascii && (in!=stdin) && *name && stat(name, &f)!= -1) {
  2100. X        mode=0;
  2101. X        /*
  2102. X         * Translate amiga file modes into UNIX file modes
  2103. X         *
  2104. X         */
  2105. X        if((f.st_attr&FIBF_READ)==0) mode|=0400;
  2106. X        if((f.st_attr&FIBF_WRITE)==0) mode|=0200;
  2107. X        if((f.st_attr&FIBF_EXECUTE)==0) mode|=0100;
  2108. X        /*
  2109. X         * Unix's st_mtime starts from 1 Jan 1970 GMT,
  2110. X         * while Manx's st_mtime starts from 1 Jan 1978
  2111. X         *
  2112. X         * So we adjust before sending (iff gmt_diff has been set)
  2113. X         */
  2114. X        sprintf(p, "%lu %lo %o", f.st_size,
  2115. X         gmt_diff_set?f.st_mtime+24*60*60*(6*365+2*366)-gmt_diff*60*60:0
  2116. X             ,SendProtect?mode:0);
  2117. X    }
  2118. X#endif
  2119. X    /* force 1k blocks if name won't fit in 128 byte block */
  2120. X    if (txbuf[125])
  2121. X        blklen=KSIZE;
  2122. X    else {        /* A little goodie for IMP/KMD */
  2123. X        if (Zmodem)
  2124. X            blklen = SECSIZ;
  2125. X        txbuf[127] = (f.st_size + 127) >>7;
  2126. X        txbuf[126] = (f.st_size + 127) >>15;
  2127. X    }
  2128. X    if (Zmodem)
  2129. X        return zsendfile(txbuf, 1+strlen(p)+(p-txbuf));
  2130. X    if (wcputsec(txbuf, 0, SECSIZ)==ERROR)
  2131. X        return ERROR;
  2132. X    return OK;
  2133. X}
  2134. X
  2135. Xgetnak()
  2136. X{
  2137. X    register firstch;
  2138. X
  2139. X    Lastrx = 0;
  2140. X    for (;;) {
  2141. X        switch (firstch = readock(800,1)) {
  2142. X
  2143. X        case ZPAD:
  2144. X            if (getzrxinit())
  2145. X                return ERROR;
  2146. X            Ascii = 0;
  2147. X            return FALSE;
  2148. X        case TIMEOUT:
  2149. X            zperr("Timeout on pathname");
  2150. X            return TRUE;
  2151. X        case WANTG:
  2152. X#ifdef USG
  2153. X            mode(2);        /* Set cbreak, XON/XOFF, etc. */
  2154. X#endif
  2155. X            Optiong = TRUE;
  2156. X            blklen=KSIZE;
  2157. X        case WANTCRC:
  2158. X            Crcflg = TRUE;
  2159. X        case NAK:
  2160. X            return FALSE;
  2161. X        case CAN:
  2162. X            if ((firstch = readock(20,1)) == CAN && Lastrx == CAN)
  2163. X                return TRUE;
  2164. X        default:
  2165. X            break;
  2166. X        }
  2167. X        Lastrx = firstch;
  2168. X    }
  2169. X}
  2170. X
  2171. X
  2172. Xwctx(flen)
  2173. Xlong flen;
  2174. X{
  2175. X    register int thisblklen;
  2176. X    register int sectnum, attempts, firstch;
  2177. X    long charssent;
  2178. X
  2179. X    charssent = 0;    firstsec=TRUE;    thisblklen = blklen;
  2180. X    vfile("wctx:file length=%ld", flen);
  2181. X
  2182. X    while ((firstch=readock(Rxtimeout, 2))!=NAK && firstch != WANTCRC
  2183. X      && firstch != WANTG && firstch!=TIMEOUT && firstch!=CAN)
  2184. X        ;
  2185. X    if (firstch==CAN) {
  2186. X        zperr("Receiver CANcelled");
  2187. X        return ERROR;
  2188. X    }
  2189. X    if (firstch==WANTCRC)
  2190. X        Crcflg=TRUE;
  2191. X    if (firstch==WANTG)
  2192. X        Crcflg=TRUE;
  2193. X    sectnum=0;
  2194. X    for (;;) {
  2195. X        if (flen <= (charssent + 896L))
  2196. X            thisblklen = 128;
  2197. X        if ( !filbuf(txbuf, thisblklen))
  2198. X            break;
  2199. X        if (wcputsec(txbuf, ++sectnum, thisblklen)==ERROR)
  2200. X            return ERROR;
  2201. X        charssent += thisblklen;
  2202. X    }
  2203. X    fclose(in);
  2204. X    attempts=0;
  2205. X    do {
  2206. X        purgeline();
  2207. X        sendline(EOT);
  2208. X        fflush(stdout);
  2209. X        ++attempts;
  2210. X    }
  2211. X        while ((firstch=(readock(Rxtimeout, 1)) != ACK) && attempts < RETRYMAX);
  2212. X    if (attempts == RETRYMAX) {
  2213. X        zperr("No ACK on EOT");
  2214. X        return ERROR;
  2215. X    }
  2216. X    else
  2217. X        return OK;
  2218. X}
  2219. X
  2220. Xwcputsec(buf, sectnum, cseclen)
  2221. Xchar *buf;
  2222. Xint sectnum;
  2223. Xint cseclen;    /* data length of this sector to send */
  2224. X{
  2225. X    register checksum, wcj;
  2226. X    register char *cp;
  2227. X    unsigned oldcrc;
  2228. X    int firstch;
  2229. X    int attempts;
  2230. X
  2231. X    firstch=0;    /* part of logic to detect CAN CAN */
  2232. X
  2233. X    if (Verbose>2)
  2234. X        fprintf(stderr, "Sector %3d %2dk\n", Totsecs, Totsecs/8 );
  2235. X    else if (Verbose>1)
  2236. X        fprintf(stderr, "\rSector %3d %2dk ", Totsecs, Totsecs/8 );
  2237. X    for (attempts=0; attempts <= RETRYMAX; attempts++) {
  2238. X        Lastrx= firstch;
  2239. X        sendline(cseclen==KSIZE?STX:SOH);
  2240. X        sendline(sectnum);
  2241. X        sendline(-sectnum -1);
  2242. X        oldcrc=checksum=0;
  2243. X        for (wcj=cseclen,cp=buf; --wcj>=0; ) {
  2244. X            sendline(*cp);
  2245. X            oldcrc=updcrc((0377& *cp), oldcrc);
  2246. X            checksum += *cp++;
  2247. X        }
  2248. X        if (Crcflg) {
  2249. X            oldcrc=updcrc(0,updcrc(0,oldcrc));
  2250. X            sendline((int)oldcrc>>8);
  2251. X            sendline((int)oldcrc);
  2252. X        }
  2253. X        else
  2254. X            sendline(checksum);
  2255. X#ifdef AMIGA
  2256. X        flushmo();
  2257. X#endif
  2258. X
  2259. X        if (Optiong) {
  2260. X            firstsec = FALSE; return OK;
  2261. X        }
  2262. X        firstch = readock(Rxtimeout, (Noeofseen&§num) ? 2:1);
  2263. Xgotnak:
  2264. X        switch (firstch) {
  2265. X        case CAN:
  2266. X            if(Lastrx == CAN) {
  2267. Xcancan:
  2268. X                zperr("Cancelled");  return ERROR;
  2269. X            }
  2270. X            break;
  2271. X        case TIMEOUT:
  2272. X            zperr("Timeout on sector ACK"); continue;
  2273. X        case WANTCRC:
  2274. X            if (firstsec)
  2275. X                Crcflg = TRUE;
  2276. X        case NAK:
  2277. X            zperr("NAK on sector"); continue;
  2278. X        case ACK:
  2279. X            firstsec=FALSE;
  2280. X            Totsecs += (cseclen>>7);
  2281. X            return OK;
  2282. X        case ERROR:
  2283. X            zperr("Got burst for sector ACK"); break;
  2284. X        default:
  2285. X            zperr("Got %02x for sector ACK", firstch); break;
  2286. X        }
  2287. X        for (;;) {
  2288. X            Lastrx = firstch;
  2289. X            if ((firstch = readock(Rxtimeout, 2)) == TIMEOUT)
  2290. X                break;
  2291. X            if (firstch == NAK || firstch == WANTCRC)
  2292. X                goto gotnak;
  2293. X            if (firstch == CAN && Lastrx == CAN)
  2294. X                goto cancan;
  2295. X        }
  2296. X    }
  2297. X    zperr("Retry Count Exceeded");
  2298. X    return ERROR;
  2299. X}
  2300. X
  2301. X/* fill buf with count chars padding with ^Z for CPM */
  2302. Xfilbuf(buf, count)
  2303. Xregister char *buf;
  2304. X{
  2305. X    register c, m;
  2306. X
  2307. X    if ( !Ascii) {
  2308. X        m = read(fileno(in), buf, count);
  2309. X        if (m <= 0)
  2310. X            return 0;
  2311. X        while (m < count)
  2312. X            buf[m++] = 032;
  2313. X        return count;
  2314. X    }
  2315. X    m=count;
  2316. X    if (Lfseen) {
  2317. X        *buf++ = 012; --m; Lfseen = 0;
  2318. X    }
  2319. X    while ((c=getc(in))!=EOF) {
  2320. X        if (c == 012) {
  2321. X            *buf++ = 015;
  2322. X            if (--m == 0) {
  2323. X                Lfseen = TRUE; break;
  2324. X            }
  2325. X        }
  2326. X        *buf++ =c;
  2327. X        if (--m == 0)
  2328. X            break;
  2329. X    }
  2330. X    if (m==count)
  2331. X        return 0;
  2332. X    else
  2333. X        while (--m>=0)
  2334. X            *buf++ = CPMEOF;
  2335. X    return count;
  2336. X}
  2337. X/* fill buf with count chars */
  2338. Xzfilbuf(buf, count)
  2339. Xregister char *buf;
  2340. X{
  2341. X    register c, m;
  2342. X
  2343. X    m=count;
  2344. X    while ((c=getc(in))!=EOF) {
  2345. X        *buf++ =c;
  2346. X        if (--m == 0)
  2347. X            break;
  2348. X    }
  2349. X    return (count - m);
  2350. X}
  2351. X
  2352. X/* VARARGS1 */
  2353. Xvfile(f, a, b, c)
  2354. Xregister char *f;
  2355. X{
  2356. X    if (Verbose > 2) {
  2357. X        fprintf(stderr, f, a, b, c);
  2358. X        fprintf(stderr, "\n");
  2359. X    }
  2360. X}
  2361. X
  2362. X#ifndef AMIGA
  2363. Xalrm()
  2364. X{
  2365. X    longjmp(tohere, -1);
  2366. X}
  2367. X
  2368. X
  2369. X/*
  2370. X * readock(timeout, count) reads character(s) from file descriptor 0
  2371. X *  (1 <= count <= 3)
  2372. X * it attempts to read count characters. If it gets more than one,
  2373. X * it is an error unless all are CAN
  2374. X * (otherwise, only normal response is ACK, CAN, or C)
  2375. X *  Only looks for one if Optiong, which signifies cbreak, not raw input
  2376. X *
  2377. X * timeout is in tenths of seconds
  2378. X */
  2379. Xreadock(timeout, count)
  2380. X{
  2381. X    register int c;
  2382. X    static char byt[5];
  2383. X
  2384. X    if (Optiong)
  2385. X        count = 1;    /* Special hack for cbreak */
  2386. X
  2387. X    fflush(stdout);
  2388. X    if (setjmp(tohere)) {
  2389. X        zperr("TIMEOUT");
  2390. X        return TIMEOUT;
  2391. X    }
  2392. X    c = timeout/10;
  2393. X    if (c<2)
  2394. X        c=2;
  2395. X    if (Verbose>5) {
  2396. X        fprintf(stderr, "Timeout=%d Calling alarm(%d) ", timeout, c);
  2397. X        byt[1] = 0;
  2398. X    }
  2399. X    signal(SIGALRM, alrm); alarm(c);
  2400. X#ifdef ONEREAD
  2401. X    c=read(iofd, byt, 1);           /* regulus raw read is unique */
  2402. X#else
  2403. X    c=read(iofd, byt, count);
  2404. X#endif
  2405. X    alarm(0);
  2406. X    if (Verbose>5)
  2407. X        fprintf(stderr, "ret cnt=%d %x %x\n", c, byt[0], byt[1]);
  2408. X    if (c<1)
  2409. X        return TIMEOUT;
  2410. X    if (c==1)
  2411. X        return (byt[0]&0377);
  2412. X    else
  2413. X        while (c)
  2414. X            if (byt[--c] != CAN)
  2415. X                return ERROR;
  2416. X    return CAN;
  2417. X}
  2418. X#else /* AMIGA */
  2419. X#ifdef BUG
  2420. X /*
  2421. X  * This code implements what the readock function is supposed to do
  2422. X  * but it breaks zmodem's YMODEM protocol for some strange reason???
  2423. X  * So I've just ifdef'd it out and replaced it with another function
  2424. X  * that forces 1 byte reads.
  2425. X  */
  2426. Xreadock(timeout,count)
  2427. Xint timeout,count;
  2428. X{
  2429. X    ULONG mask;
  2430. X    int act;
  2431. X    static char byt[5];
  2432. X
  2433. X    IOTime->tr_time.tv_secs = timeout/10;
  2434. X    IOTime->tr_time.tv_micro = 100000*(timeout%10); /* tenths of seconds */
  2435. X    IOTime->tr_node.io_Command = TR_ADDREQUEST;
  2436. X    SendIO(IOTime);
  2437. X    SendSer(count,byt);
  2438. X    mask=Wait( InSerSigMask | IOTimeSigMask | SIGBREAKF_CTRL_C);
  2439. X    if ((mask&SIGBREAKF_CTRL_C)!=0) {
  2440. X    KillIO(IOTime,mask);
  2441. X    KillIO( (struct IOStdReq *)InSer,mask);
  2442. X    Waitbibi();
  2443. X    }
  2444. X    else if ((mask&InSerSigMask)!=0) {
  2445. X    KillIO(IOTime,mask);
  2446. X    GetMsg(InSerPort);
  2447. X    act=(int)InSer->IOSer.io_Actual;
  2448. X    if (Verbose>5)
  2449. X        fprintf(stderr, "ret cnt=%d %x %x\n", act, byt[0], byt[1]);
  2450. X    if (act==1)
  2451. X        return (byt[0]&0377);
  2452. X    else
  2453. X        while (act)
  2454. X        if (byt[--act] != CAN)
  2455. X            return ERROR;
  2456. X    return CAN;
  2457. X    }
  2458. X    else  { /* it was the timer signal */
  2459. X    KillIO( (struct IOStdReq *)InSer,mask);
  2460. X    WaitIO(IOTime);
  2461. X    zperr("TIMEOUT");
  2462. X    return TIMEOUT;
  2463. X    }
  2464. X}
  2465. X#else /* KLUDGE */
  2466. Xreadock(timeout,count)
  2467. Xint timeout,count;
  2468. X{
  2469. X    int act;
  2470. X    static char byt[5];
  2471. X
  2472. X    if((byt[0]=ReadSer(timeout))==TIMEOUT) {
  2473. X    zperr("TIMEOUT");
  2474. X    return TIMEOUT;
  2475. X    }
  2476. X    act=rdchk()+1;
  2477. X    if(act>1) byt[1]=ReadSer(timeout);
  2478. X    if (Verbose>5)
  2479. X    fprintf(stderr, "ret cnt=%d %x %x\n", act, byt[0], byt[1]);
  2480. X    if (act==1)
  2481. X    return (byt[0]&0377);
  2482. X    else
  2483. X    while (act)
  2484. X        if (byt[--act] != CAN)
  2485. X        return ERROR;
  2486. X    return CAN;
  2487. X}
  2488. X#endif /* BUG */
  2489. X#endif /* AMIGA */
  2490. X
  2491. Xreadline(n)
  2492. X{
  2493. X    return (readock(n, 1));
  2494. X}
  2495. X
  2496. Xpurgeline()
  2497. X{
  2498. X#ifdef AMIGA
  2499. X    PurgeSer();
  2500. X#else
  2501. X#ifdef USG
  2502. X    ioctl(iofd, TCFLSH, 0);
  2503. X#else
  2504. X    lseek(iofd, 0L, 2);
  2505. X#endif
  2506. X#endif /* AMIGA */
  2507. X}
  2508. X
  2509. X/* send cancel string to get the other end to shut up */
  2510. Xcanit()
  2511. X{
  2512. X    static char canistr[] = {
  2513. X     24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  2514. X    };
  2515. X
  2516. X#ifndef AMIGA
  2517. X    printf(canistr);
  2518. X    fflush(stdout);
  2519. X#else
  2520. X    LWriteSer(canistr,strlen(canistr));
  2521. X#endif
  2522. X}
  2523. X
  2524. X/*
  2525. X * Log an error
  2526. X */
  2527. X/*VARARGS1*/
  2528. Xzperr(s,p,u)
  2529. Xchar *s, *p, *u;
  2530. X{
  2531. X    if (Verbose <= 0)
  2532. X        return;
  2533. X    fprintf(stderr, "\nRetry %d: ", errors);
  2534. X    fprintf(stderr, s, p, u);
  2535. X    fprintf(stderr, "\n");
  2536. X}
  2537. X#ifndef AMIGA
  2538. X/*
  2539. X * return 1 iff stdout and stderr are different devices
  2540. X *  indicating this program operating with a modem on a
  2541. X *  different line
  2542. X */
  2543. Xfrom_cu()
  2544. X{
  2545. X    struct stat a, b;
  2546. X    fstat(1, &a); fstat(2, &b);
  2547. X    return (a.st_rdev != b.st_rdev);
  2548. X}
  2549. X#else /* AMIGA */
  2550. Xfrom_cu()
  2551. X{
  2552. X    return TRUE;
  2553. X}
  2554. X#endif
  2555. X
  2556. X/*
  2557. X * substr(string, token) searches for token in string s
  2558. X * returns pointer to token within string if found, NULL otherwise
  2559. X */
  2560. Xchar *
  2561. Xsubstr(s, t)
  2562. Xregister char *s,*t;
  2563. X{
  2564. X    register char *ss,*tt;
  2565. X    /* search for first char of token */
  2566. X    for (ss=s; *s; s++)
  2567. X        if (*s == *t)
  2568. X            /* compare token with substring */
  2569. X            for (ss=s,tt=t; ;) {
  2570. X                if (*tt == 0)
  2571. X                    return s;
  2572. X                if (*ss++ != *tt++)
  2573. X                    break;
  2574. X            }
  2575. X    return NULL;
  2576. X}
  2577. X
  2578. Xchar *babble[] = {
  2579. X    "Send file(s) with ZMODEM/YMODEM/XMODEM Protocol",
  2580. X    "       (Y) = Option applies to YMODEM only",
  2581. X    "       (Z) = Option applies to ZMODEM only",
  2582. X#ifndef AMIGA
  2583. X    "Usage: sz [-12+abdefkLlNnquvwYy] [-] file ...",
  2584. X    "       sz [-12Ceqv] -c COMMAND",
  2585. X    "       sb [-12adfkquv] [-] file ...",
  2586. X    "       sx [-12akquv] [-] file",
  2587. X#else
  2588. X    "Usage: sz [-+abBdefhIkLmlNnqQTuvwXYy] file ...",
  2589. X    "       sz [-CehIqQTv] -c COMMAND",
  2590. X    "       sb [-adfhIkqQTuv] file ...",
  2591. X    "       sx [-ahIkqQTuv] file",
  2592. X#endif
  2593. X#ifndef AMIGA
  2594. X    "       1 Use stdout for modem input",
  2595. X#ifdef CSTOPB
  2596. X    "       2 Use 2 stop bits",
  2597. X#endif
  2598. X#endif
  2599. X    "       + Append to existing destination file (Z)",
  2600. X    "       a (ASCII) change NL to CR/LF",
  2601. X    "       b Binary file transfer override",
  2602. X#ifdef AMIGA
  2603. X    "       B Ymodem file transfer",
  2604. X#endif
  2605. X    "       c send COMMAND (Z)",
  2606. X    "       d Change '.' to '/' in pathnames (Y/Z)",
  2607. X    "       e Escape all control characters (Z)",
  2608. X    "       f send Full pathname (Y/Z)",
  2609. X#ifdef AMIGA
  2610. X    "       h Half duplex mode (only for Terminal mode)",
  2611. X#endif
  2612. X    "       i send COMMAND, ack Immediately (Z)",
  2613. X#ifdef AMIGA
  2614. X    "       I use serial parameters from ZMODEM.INIT file",
  2615. X#endif
  2616. X    "       k Send 1024 byte packets (Y)",
  2617. X    "       L N Limit subpacket length to N bytes (Z)",
  2618. X    "       l N Limit frame length to N bytes (l>=L) (Z)",
  2619. X#ifdef AMIGA
  2620. X    "       m Don't send file mode bits",
  2621. X#endif
  2622. X    "       n send file if source newer (Z)",
  2623. X    "       N send file if source newer or longer (Z)",
  2624. X    "       o Use 16 bit CRC instead of 32 bit CRC (Z)",
  2625. X    "       p Protect existing destination file (Z)",
  2626. X    "       r Resume/Recover interrupted file transfer (Z)",
  2627. X    "       q Quiet (no progress reports)",
  2628. X#ifdef AMIGA
  2629. X    "       Q Quit without waiting for click in close box",
  2630. X    "       T enter Terminal mode before transferring",
  2631. X#endif
  2632. X    "       u Unlink file after transmission",
  2633. X    "       v Verbose - provide debugging information",
  2634. X    "       w N Window is N bytes (Z)",
  2635. X#ifdef AMIGA
  2636. X    "       X Xmodem file transfer",
  2637. X#endif
  2638. X    "       Y Yes, overwrite existing file, skip if not present at rx (Z)",
  2639. X    "       y Yes, overwrite existing file (Z)",
  2640. X#ifndef AMIGA
  2641. X    "- as pathname sends standard input as sPID.sz or environment ONAME",
  2642. X#endif
  2643. X    ""
  2644. X};
  2645. X
  2646. X#ifdef AMIGA
  2647. Xusage()
  2648. X{
  2649. X  char **pp;
  2650. X  int i,n,rows,cols,height;
  2651. X  struct Screen Scr;
  2652. X  char rep[20];
  2653. X
  2654. X    /* Expand window, to show as many lines at once as possible */
  2655. X    MoveWindow(Win,-Win->LeftEdge,-Win->TopEdge);
  2656. X    if( !GetScreenData(&Scr,sizeof(struct Screen),WBENCHSCREEN)) {
  2657. X    puts("Couldn't get screen size");
  2658. X    CleanUp();
  2659. X    exit(1);
  2660. X    }
  2661. X    rows=Scr.Height;
  2662. X    cols=Scr.Width;
  2663. X    SizeWindow(Win,cols>640?640-Win->Width:cols-Win->Width,
  2664. X           rows-Win->Height);
  2665. X    Delay(15);  /* Wait until window is resized */
  2666. X    ConPutStr(ConWriteReq,"\2330 q"); /* get window bounds */
  2667. X    n = 0;
  2668. X    while((rep[n] = ConGetC(ConReadReq)) != 'r' && n++ < 20)
  2669. X    ;
  2670. X    height=0;
  2671. X    i=5;
  2672. X    while(rep[i]>='0' && rep[i]<='9' && i<n) {
  2673. X    height*=10;
  2674. X    height+=rep[i++]-'0';
  2675. X    }
  2676. X    for (pp=babble,i=1; **pp; ++pp,i++) {
  2677. X    fprintf(stderr, "%s\n", *pp);
  2678. X    if((i%height)==(height-1)) {
  2679. X        WaitKey();
  2680. X        ConPutStr(ConWriteReq,"\2331\0731\110\233\112");  /* Erase screen */
  2681. X    }
  2682. X    }
  2683. X    fprintf(stderr,"%s by Chuck Forsberg, amiga version 1.0 by Frank Harper\n",VERSION);
  2684. X    WaitKey();
  2685. X    bibi(1);
  2686. X}
  2687. X
  2688. XWaitKey()
  2689. X{
  2690. X  char ConChar;
  2691. X  ULONG mask,IntuiMask,ConInMask;
  2692. X
  2693. X    IntuiMask = 1 << (Win->UserPort->mp_SigBit);
  2694. X    ConInMask = 1 << (ConReadPort->mp_SigBit);
  2695. X    ConPutStr(ConWriteReq,"\23307\155 Press a key \23300\155");
  2696. X    QueueRead(ConReadReq,&ConChar);
  2697. X    mask=Wait(ConInMask|IntuiMask);
  2698. X    if(CheckQuit()) {       /* Hit close box? */
  2699. X    KillIO(ConReadReq);
  2700. X    bibi(1);
  2701. X    }
  2702. X    GetMsg(ConReadPort);
  2703. X}
  2704. X#else
  2705. Xusage()
  2706. X{
  2707. X    char **pp;
  2708. X    for (pp=babble; **pp; ++pp)
  2709. X        fprintf(stderr, "%s\n", *pp);
  2710. X    fprintf(stderr, "%s for %s by Chuck Forsberg\n", VERSION,OS);
  2711. X    exit(1);
  2712. X}
  2713. X#endif
  2714. X/*
  2715. X * Get the receiver's init parameters
  2716. X */
  2717. Xgetzrxinit()
  2718. X{
  2719. X    register n;
  2720. X    struct stat f;
  2721. X
  2722. X    for (n=10; --n>=0; ) {
  2723. X
  2724. X        switch (zgethdr(Rxhdr, 1)) {
  2725. X        case ZCHALLENGE:    /* Echo receiver's challenge numbr */
  2726. X            stohdr(Rxpos);
  2727. X            zshhdr(ZACK, Txhdr);
  2728. X            continue;
  2729. X        case ZCOMMAND:        /* They didn't see out ZRQINIT */
  2730. X            stohdr(0L);
  2731. X            zshhdr(ZRQINIT, Txhdr);
  2732. X            continue;
  2733. X        case ZRINIT:
  2734. X            Rxflags = 0377 & Rxhdr[ZF0];
  2735. X            Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
  2736. X            Zctlesc |= Rxflags & TESCCTL;
  2737. X            Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
  2738. X            vfile("Rxbuflen=%d Tframlen=%d", Rxbuflen, Tframlen);
  2739. X#ifndef AMIGA
  2740. X            if ( !Fromcu)
  2741. X                signal(SIGINT, SIG_IGN);
  2742. X#ifdef USG
  2743. X            mode(2);        /* Set cbreak, XON/XOFF, etc. */
  2744. X#endif
  2745. X#ifndef READCHECK
  2746. X#ifndef USG
  2747. X            /* Use 1024 byte frames if no sample/interrupt */
  2748. X            if (Rxbuflen < 32 || Rxbuflen > 1024) {
  2749. X                Rxbuflen = 1024;
  2750. X                vfile("Rxbuflen=%d", Rxbuflen);
  2751. X            }
  2752. X#endif
  2753. X#endif
  2754. X#endif
  2755. X            /* Override to force shorter frame length */
  2756. X            if (Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32))
  2757. X                Rxbuflen = Tframlen;
  2758. X            if ( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024))
  2759. X                Rxbuflen = Tframlen;
  2760. X            vfile("Rxbuflen=%d", Rxbuflen);
  2761. X
  2762. X#ifndef AMIGA
  2763. X            /* If using a pipe for testing set lower buf len */
  2764. X            fstat(iofd, &f);
  2765. X            if ((f.st_mode & S_IFMT) != S_IFCHR
  2766. X              && (Rxbuflen == 0 || Rxbuflen > 4096))
  2767. X                Rxbuflen = 4096;
  2768. X            /*
  2769. X             * If input is not a regular file, force ACK's each 1024
  2770. X             *  (A smarter strategey could be used here ...)
  2771. X             */
  2772. X            fstat(fileno(in), &f);
  2773. X            if (((f.st_mode & S_IFMT) != S_IFREG)
  2774. X              && (Rxbuflen == 0 || Rxbuflen > 1024))
  2775. X                Rxbuflen = 1024;
  2776. X            vfile("Rxbuflen=%d", Rxbuflen);
  2777. X#endif
  2778. X            return (sendzsinit());
  2779. X        case ZCAN:
  2780. X        case TIMEOUT:
  2781. X            return ERROR;
  2782. X        case ZRQINIT:
  2783. X            if (Rxhdr[ZF0] == ZCOMMAND)
  2784. X                continue;
  2785. X        default:
  2786. X            zshhdr(ZNAK, Txhdr);
  2787. X            continue;
  2788. X        }
  2789. X    }
  2790. X    return ERROR;
  2791. X}
  2792. X
  2793. X/* Send send-init information */
  2794. Xsendzsinit()
  2795. X{
  2796. X    register c;
  2797. X
  2798. X    if (Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL)))
  2799. X        return OK;
  2800. X    errors = 0;
  2801. X    for (;;) {
  2802. X        stohdr(0L);
  2803. X        if (Zctlesc) {
  2804. X            Txhdr[ZF0] |= TESCCTL; zshhdr(ZSINIT, Txhdr);
  2805. X        }
  2806. X        else
  2807. X            zsbhdr(ZSINIT, Txhdr);
  2808. X        zsdata(Myattn, 1+strlen(Myattn), ZCRCW);
  2809. X        c = zgethdr(Rxhdr, 1);
  2810. X        switch (c) {
  2811. X        case ZCAN:
  2812. X            return ERROR;
  2813. X        case ZACK:
  2814. X            return OK;
  2815. X        default:
  2816. X            if (++errors > 19)
  2817. X                return ERROR;
  2818. X            continue;
  2819. X        }
  2820. X    }
  2821. X}
  2822. X
  2823. X/* Send file name and related info */
  2824. Xzsendfile(buf, blen)
  2825. Xchar *buf;
  2826. X{
  2827. X    register c;
  2828. X
  2829. X    for (;;) {
  2830. X        Txhdr[ZF0] = Lzconv;    /* file conversion request */
  2831. X        Txhdr[ZF1] = Lzmanag;    /* file management request */
  2832. X        if (Lskipnocor)
  2833. X            Txhdr[ZF1] |= ZMSKNOLOC;
  2834. X        Txhdr[ZF2] = Lztrans;    /* file transport request */
  2835. X        Txhdr[ZF3] = 0;
  2836. X        zsbhdr(ZFILE, Txhdr);
  2837. X        zsdata(buf, blen, ZCRCW);
  2838. Xagain:
  2839. X        c = zgethdr(Rxhdr, 1);
  2840. X        switch (c) {
  2841. X        case ZRINIT:
  2842. X            while ((c = readline(50)) > 0)
  2843. X                if (c == ZPAD) {
  2844. X                    goto again;
  2845. X                }
  2846. X            /* **** FALL THRU TO **** */
  2847. X        default:
  2848. X            continue;
  2849. X        case ZCAN:
  2850. X        case TIMEOUT:
  2851. X        case ZABORT:
  2852. X        case ZFIN:
  2853. X            return ERROR;
  2854. X        case ZSKIP:
  2855. X            fclose(in); return c;
  2856. X        case ZRPOS:
  2857. X            /*
  2858. X             * Suppress zcrcw request otherwise triggered by
  2859. X             * lastyunc==bytcnt
  2860. X             */
  2861. X            Lastsync = (bytcnt = Txpos = Rxpos) -1;
  2862. X            fseek(in, Rxpos, 0);
  2863. X            Dontread = FALSE;
  2864. X            return zsendfdata();
  2865. X        }
  2866. X    }
  2867. X}
  2868. X
  2869. X/* Send the data in the file */
  2870. Xzsendfdata()
  2871. X{
  2872. X    register c, e, n;
  2873. X    register newcnt;
  2874. X    register long tcount = 0;
  2875. X    int junkcount;        /* Counts garbage chars received by TX */
  2876. X    static int tleft = 6;    /* Counter for test mode */
  2877. X
  2878. X    if (Baudrate > 300)
  2879. X        blklen = 256;
  2880. X    if (Baudrate > 1200)
  2881. X        blklen = 512;
  2882. X    if (Baudrate > 2400)
  2883. X        blklen = KSIZE;
  2884. X    if (Rxbuflen && blklen>Rxbuflen)
  2885. X        blklen = Rxbuflen;
  2886. X    if (blkopt && blklen > blkopt)
  2887. X        blklen = blkopt;
  2888. X    vfile("Rxbuflen=%d blklen=%d", Rxbuflen, blklen);
  2889. X    vfile("Txwindow = %u Txwspac = %d", Txwindow, Txwspac);
  2890. X    Lrxpos = 0;
  2891. X    junkcount = 0;
  2892. X    Beenhereb4 = FALSE;
  2893. Xsomemore:
  2894. X#ifndef AMIGA
  2895. X    if (setjmp(intrjmp)) {
  2896. X#else
  2897. X    goto start; /* get things going right away */
  2898. X#endif
  2899. Xwaitack:
  2900. X        junkcount = 0;
  2901. X        c = getinsync(0);
  2902. Xgotack:
  2903. X        switch (c) {
  2904. X        default:
  2905. X        case ZCAN:
  2906. X            fclose(in);
  2907. X            return ERROR;
  2908. X        case ZSKIP:
  2909. X            fclose(in);
  2910. X            return c;
  2911. X        case ZACK:
  2912. X        case ZRPOS:
  2913. X            break;
  2914. X        case ZRINIT:
  2915. X            return OK;
  2916. X        }
  2917. X#ifdef READCHECK
  2918. X        /*
  2919. X         * If the reverse channel can be tested for data,
  2920. X         *  this logic may be used to detect error packets
  2921. X         *  sent by the receiver, in place of setjmp/longjmp
  2922. X         *  rdchk(fdes) returns non 0 if a character is available
  2923. X         */
  2924. X#ifndef AMIGA
  2925. X        while (rdchk(iofd)) {
  2926. X#else
  2927. X        while (rdchk())     {
  2928. X#endif
  2929. X#ifdef SVR2
  2930. X            switch (checked)
  2931. X#else
  2932. X            switch (readline(1))
  2933. X#endif
  2934. X            {
  2935. X            case CAN:
  2936. X            case ZPAD:
  2937. X                c = getinsync(1);
  2938. X                goto gotack;
  2939. X            case XOFF:        /* Wait a while for an XON */
  2940. X            case XOFF|0200:
  2941. X                readline(100);
  2942. X            }
  2943. X        }
  2944. X#endif /* READCHECK */
  2945. X#ifndef AMIGA
  2946. X    }
  2947. X
  2948. X    if ( !Fromcu)
  2949. X        signal(SIGINT, onintr);
  2950. X#endif
  2951. Xstart:
  2952. X    newcnt = Rxbuflen;
  2953. X    Txwcnt = 0;
  2954. X    stohdr(Txpos);
  2955. X    zsbhdr(ZDATA, Txhdr);
  2956. X#ifndef AMIGA
  2957. X    /*
  2958. X     * Special testing mode.  This should force receiver to Attn,ZRPOS
  2959. X     *  many times.  Each time the signal should be caught, causing the
  2960. X     *  file to be started over from the beginning.
  2961. X     */
  2962. X    if (Testattn) {
  2963. X        if ( --tleft)
  2964. X            while (tcount < 20000) {
  2965. X                printf(qbf); fflush(stdout);
  2966. X                tcount += strlen(qbf);
  2967. X#ifdef READCHECK
  2968. X                while (rdchk(iofd)) {
  2969. X#ifdef SVR2
  2970. X                    switch (checked)
  2971. X#else
  2972. X                    switch (readline(1))
  2973. X#endif
  2974. X                    {
  2975. X                    case CAN:
  2976. X                    case ZPAD:
  2977. X#ifdef TCFLSH
  2978. X                        ioctl(iofd, TCFLSH, 1);
  2979. X#endif
  2980. X                        goto waitack;
  2981. X                    case XOFF:    /* Wait for XON */
  2982. X                    case XOFF|0200:
  2983. X                        readline(100);
  2984. X                    }
  2985. X                }
  2986. X#endif /* READCHECK */
  2987. X            }
  2988. X        signal(SIGINT, SIG_IGN); canit();
  2989. X        sleep(3); purgeline(); mode(0);
  2990. X        printf("\nsz: Tcount = %ld\n", tcount);
  2991. X        if (tleft) {
  2992. X            printf("ERROR: Interrupts Not Caught\n");
  2993. X            exit(1);
  2994. X        }
  2995. X        exit(0);
  2996. X    }
  2997. X#endif
  2998. X
  2999. X    do {
  3000. X        if (Dontread) {
  3001. X            n = Lastn;
  3002. X        } else {
  3003. X            n = zfilbuf(txbuf, blklen);
  3004. X            Lastread = Txpos;  Lastn = n;
  3005. X        }
  3006. X        Dontread = FALSE;
  3007. X        if (n < blklen)
  3008. X            e = ZCRCE;
  3009. X        else if (junkcount > 3)
  3010. X            e = ZCRCW;
  3011. X        else if (bytcnt == Lastsync)
  3012. X            e = ZCRCW;
  3013. X        else if (Rxbuflen && (newcnt -= n) <= 0)
  3014. X            e = ZCRCW;
  3015. X        else if (Txwindow && (Txwcnt += n) >= Txwspac) {
  3016. X            Txwcnt = 0;  e = ZCRCQ;
  3017. X        }
  3018. X        else
  3019. X            e = ZCRCG;
  3020. X        if (Verbose>1)
  3021. X            fprintf(stderr, "\r%7ld ZMODEM%s    ",
  3022. X              Txpos, Crc32t?" CRC-32":"");
  3023. X        zsdata(txbuf, n, e);
  3024. X        bytcnt = Txpos += n;
  3025. X        if (e == ZCRCW)
  3026. X            goto waitack;
  3027. X#ifdef READCHECK
  3028. X        /*
  3029. X         * If the reverse channel can be tested for data,
  3030. X         *  this logic may be used to detect error packets
  3031. X         *  sent by the receiver, in place of setjmp/longjmp
  3032. X         *  rdchk(fdes) returns non 0 if a character is available
  3033. X         */
  3034. X        fflush(stdout);
  3035. X#ifndef AMIGA
  3036. X        while (rdchk(iofd)) {
  3037. X#else
  3038. X        while (rdchk()) {
  3039. X#endif
  3040. X#ifdef SVR2
  3041. X            switch (checked)
  3042. X#else
  3043. X            switch (readline(1))
  3044. X#endif
  3045. X            {
  3046. X            case CAN:
  3047. X            case ZPAD:
  3048. X                c = getinsync(1);
  3049. X                if (c == ZACK)
  3050. X                    break;
  3051. X#ifdef TCFLSH
  3052. X                ioctl(iofd, TCFLSH, 1);
  3053. X#endif
  3054. X                /* zcrce - dinna wanna starta ping-pong game */
  3055. X                zsdata(txbuf, 0, ZCRCE);
  3056. X                goto gotack;
  3057. X            case XOFF:        /* Wait a while for an XON */
  3058. X            case XOFF|0200:
  3059. X                readline(100);
  3060. X            default:
  3061. X                ++junkcount;
  3062. X            }
  3063. X        }
  3064. X#endif    /* READCHECK */
  3065. X        if (Txwindow) {
  3066. X            while ((tcount = Txpos - Lrxpos) >= Txwindow) {
  3067. X                vfile("%ld window >= %u", tcount, Txwindow);
  3068. X                if (e != ZCRCQ)
  3069. X                    zsdata(txbuf, 0, e = ZCRCQ);
  3070. X                c = getinsync(1);
  3071. X                if (c != ZACK) {
  3072. X#ifdef TCFLSH
  3073. X                    ioctl(iofd, TCFLSH, 1);
  3074. X#endif
  3075. X                    zsdata(txbuf, 0, ZCRCE);
  3076. X                    goto gotack;
  3077. X                }
  3078. X            }
  3079. X            vfile("window = %ld", tcount);
  3080. X        }
  3081. X    } while (n == blklen);
  3082. X#ifndef AMIGA
  3083. X    if ( !Fromcu)
  3084. X        signal(SIGINT, SIG_IGN);
  3085. X#endif
  3086. X
  3087. X    for (;;) {
  3088. X        stohdr(Txpos);
  3089. X        zsbhdr(ZEOF, Txhdr);
  3090. X        switch (getinsync(0)) {
  3091. X        case ZACK:
  3092. X            continue;
  3093. X        case ZRPOS:
  3094. X            goto somemore;
  3095. X        case ZRINIT:
  3096. X            return OK;
  3097. X        case ZSKIP:
  3098. X            fclose(in);
  3099. X            return c;
  3100. X        default:
  3101. X            fclose(in);
  3102. X            return ERROR;
  3103. X        }
  3104. X    }
  3105. X}
  3106. X
  3107. X/*
  3108. X * Respond to receiver's complaint, get back in sync with receiver
  3109. X */
  3110. Xgetinsync(flag)
  3111. X{
  3112. X    register c;
  3113. X
  3114. X    for (;;) {
  3115. X#ifndef AMIGA
  3116. X        if (Testattn) {
  3117. X            printf("\r\n\n\n***** Signal Caught *****\r\n");
  3118. X            Rxpos = 0; c = ZRPOS;
  3119. X        } else
  3120. X#endif
  3121. X            c = zgethdr(Rxhdr, 0);
  3122. X        switch (c) {
  3123. X        case ZCAN:
  3124. X        case ZABORT:
  3125. X        case ZFIN:
  3126. X        case TIMEOUT:
  3127. X            return ERROR;
  3128. X        case ZRPOS:
  3129. X            /* ************************************* */
  3130. X            /*  If sending to a modem beuufer, you     */
  3131. X            /*   might send a break at this point to */
  3132. X            /*   dump the modem's buffer.            */
  3133. X            if (Lastn >= 0 && Lastread == Rxpos) {
  3134. X                Dontread = TRUE;
  3135. X            } else {
  3136. X                clearerr(in);   /* In case file EOF seen */
  3137. X                fseek(in, Rxpos, 0);
  3138. X            }
  3139. X            bytcnt = Lrxpos = Txpos = Rxpos;
  3140. X            if (Lastsync == Rxpos) {
  3141. X                if (++Beenhereb4 > 4)
  3142. X                    if (blklen > 256)
  3143. X                        blklen /= 2;
  3144. X            }
  3145. X            Lastsync = Rxpos;
  3146. X            return c;
  3147. X        case ZACK:
  3148. X            Lrxpos = Rxpos;
  3149. X            if (flag || Txpos == Rxpos)
  3150. X                return ZACK;
  3151. X            continue;
  3152. X        case ZRINIT:
  3153. X        case ZSKIP:
  3154. X            fclose(in);
  3155. X            return c;
  3156. X        case ERROR:
  3157. X        default:
  3158. X            zsbhdr(ZNAK, Txhdr);
  3159. X            continue;
  3160. X        }
  3161. X    }
  3162. X}
  3163. X
  3164. X
  3165. X/* Say "bibi" to the receiver, try to do it cleanly */
  3166. Xsaybibi()
  3167. X{
  3168. X    for (;;) {
  3169. X        stohdr(0L);             /* CAF Was zsbhdr - minor change */
  3170. X        zshhdr(ZFIN, Txhdr);    /*  to make debugging easier */
  3171. X        switch (zgethdr(Rxhdr, 0)) {
  3172. X        case ZFIN:
  3173. X            sendline('O'); sendline('O'); flushmo();
  3174. X        case ZCAN:
  3175. X        case TIMEOUT:
  3176. X            return;
  3177. X        }
  3178. X    }
  3179. X}
  3180. X
  3181. X/* Local screen character display function */
  3182. Xbttyout(c)
  3183. X{
  3184. X#ifndef AMIGA
  3185. X    if (Verbose)
  3186. X#else
  3187. X    if (Verbose>2)
  3188. X#endif
  3189. X        putc(c, stderr);
  3190. X}
  3191. X
  3192. X/* Send command and related info */
  3193. Xzsendcmd(buf, blen)
  3194. Xchar *buf;
  3195. X{
  3196. X    register c;
  3197. X    long cmdnum;
  3198. X
  3199. X#ifndef AMIGA
  3200. X    cmdnum = getpid();
  3201. X#endif
  3202. X    errors = 0;
  3203. X    for (;;) {
  3204. X        stohdr(cmdnum);
  3205. X        Txhdr[ZF0] = Cmdack1;
  3206. X        zsbhdr(ZCOMMAND, Txhdr);
  3207. X        zsdata(buf, blen, ZCRCW);
  3208. Xlisten:
  3209. X        Rxtimeout = 100;        /* Ten second wait for resp. */
  3210. X        c = zgethdr(Rxhdr, 1);
  3211. X
  3212. X        switch (c) {
  3213. X        case ZRINIT:
  3214. X            goto listen;    /* CAF 8-21-87 */
  3215. X        case ERROR:
  3216. X        case TIMEOUT:
  3217. X            if (++errors > Cmdtries)
  3218. X                return ERROR;
  3219. X            continue;
  3220. X        case ZCAN:
  3221. X        case ZABORT:
  3222. X        case ZFIN:
  3223. X        case ZSKIP:
  3224. X        case ZRPOS:
  3225. X            return ERROR;
  3226. X        default:
  3227. X            if (++errors > 20)
  3228. X                return ERROR;
  3229. X            continue;
  3230. X        case ZCOMPL:
  3231. X            Exitcode = Rxpos;
  3232. X            saybibi();
  3233. X            return OK;
  3234. X        case ZRQINIT:
  3235. X            vfile("******** RZ *******");
  3236. X#ifndef AMIGA
  3237. X            system("rz");
  3238. X#else
  3239. X            Execute("rz",0L,0L);
  3240. X#endif
  3241. X            vfile("******** SZ *******");
  3242. X            goto listen;
  3243. X        }
  3244. X    }
  3245. X}
  3246. X
  3247. X/*
  3248. X * If called as sb use YMODEM protocol
  3249. X */
  3250. Xchkinvok(s)
  3251. Xchar *s;
  3252. X{
  3253. X    register char *p;
  3254. X
  3255. X    p = s;
  3256. X    while (*p == '-')
  3257. X        s = ++p;
  3258. X    while (*p)
  3259. X        if (*p++ == '/')
  3260. X            s = p;
  3261. X    if (*s == 'v') {
  3262. X        Verbose=1; ++s;
  3263. X    }
  3264. X    Progname = s;
  3265. X    if (s[0]=='s' && s[1]=='b') {
  3266. X        Nozmodem = TRUE; blklen=KSIZE;
  3267. X    }
  3268. X    if (s[0]=='s' && s[1]=='x') {
  3269. X        Modem2 = TRUE;
  3270. X    }
  3271. X}
  3272. X/* End of sz.c */
  3273. SHAR_EOF
  3274. echo "End of archive 3 (of 9)"
  3275. # if you want to concatenate archives, remove anything after this line
  3276. exit
  3277.